CheckBoxFor 未绑定到模型

CheckBoxFor not binding to model

我的应用程序是这样工作的:用户从下拉列表中选择一个项目并加载局部视图。 returns 局部视图从数据库中提取数据并使用数据库中存在的值填充局部视图中的复选框的控制器操作。为此,显然模型与局部视图一起返回。这工作得很好。

现在,如果用户更改复选框的值并再次提交表单,我假设复选框的新值将绑定到模型,因此,我将能够使用它来更新数据库新的价值观。不幸的是,即使复选框被选中,一切都会返回 "false" 。我确实明白,如果没有对复选框采取任何行动,它将提交一个错误的值(即使它预先填充了数据库中现有值的复选标记),我会稍后我会关注这个问题,但我想弄清楚为什么主动检查的框没有绑定到模型。我不确定这是怎么回事,因为根据我阅读的所有内容,我的 CheckBoxFor 助手看起来是正确的。

型号

public class DataSharingModels
{
    public string ReferenceID { get; set; }
    public NBTC NBTCGroup { get; set; }
    public Contractors ContractorsGroup { get; set; }
    public Coordinators CoordinatorsGroup { get; set; }
    public NGO NGOGroup { get; set; }
    public Public PublicGroup { get; set; }
    public SelectList FA_RA_List { get; set; }

}

public class NBTC
{
    public Boolean NBTC_FA_Centroid { get; set; }
    public Boolean NBTC_FA_Bound { get; set; }
    public Boolean NBTC_RA_Centroid { get; set; }
    public Boolean NBTC_RA_Bound { get; set; }
    public Boolean NBTC_Spring_Sum { get; set; }
    public Boolean NBTC_Spring_Analysis { get; set; }
    public Boolean NBTC_Spring_Locate { get; set; }
    public Boolean NBTC_Fall_Sum { get; set; }
    public Boolean NBTC_Fall_Analysis { get; set; }
    public Boolean NBTC_Fall_Locate { get; set; }
    public Boolean NBTC_HabMon_Sum { get; set; }
    public Boolean NBTC_HabMon_Analysis { get; set; }
    public Boolean NBTC_HabMon_Locate { get; set; }
    public Boolean NBTC_HabMgmt_Sum { get; set; }
    public Boolean NBTC_HabMgmt_Analysis { get; set; }
    public Boolean NBTC_HabMgmt_Locate { get; set; }
    public Boolean NBTC_Inventory_Sum { get; set; }
    public Boolean NBTC_OpSvy_Sum { get; set; }
    public Boolean NBTC_OpSvy_Individ { get; set; }
}
//continues...

局部视图

@model xxx.Models.DataSharingModels

@using (Html.BeginForm("SetPermission", "DataSharing", FormMethod.Post, new { id = "dShareForm" }))
{
<table id="data-sharing-table">
    //a whole bunch of table set up
    <tr>
        <td rowspan="2">CIP Focal Area</td>
        <td>Centroid</td>
        <td><input type="checkbox" name="NBCIStaff" checked disabled /></td>
        <td>@Html.CheckBoxFor(m => m.NBTCGroup.NBTC_FA_Centroid, nbtcAttr)</td>
        <td>@Html.CheckBoxFor(m => m.ContractorsGroup.Contractors_FA_Centroid, contractAttr)</td>
        <td>@Html.CheckBoxFor(m => m.CoordinatorsGroup.Coordinators_FA_Centroid, coordAttr)</td>
        <td>@Html.CheckBoxFor(m => m.NGOGroup.NGO_FA_Centroid, ngoAttr)</td>
        <td>@Html.CheckBoxFor(m => m.PublicGroup.Public_FA_Centroid, publicAttr)</td>
    </tr>
    <tr>
        <td>Boundary</td>
        <td><input type="checkbox" name="NBCIStaff" checked disabled /></td>
        <td>@Html.CheckBoxFor(m => m.NBTCGroup.NBTC_FA_Bound, nbtcAttr)</td>
        <td>@Html.CheckBoxFor(m => m.ContractorsGroup.Contractors_FA_Bound, contractAttr)</td>
        <td>@Html.CheckBoxFor(m => m.CoordinatorsGroup.Coordinators_FA_Bound, coordAttr)</td>
        <td>@Html.CheckBoxFor(m => m.NGOGroup.NGO_FA_Bound, ngoAttr)</td>
        <td>@Html.CheckBoxFor(m => m.PublicGroup.Public_FA_Bound, publicAttr)</td>
    </tr>
    //it continues on like this
</table>
<button class="btn btn-default" type="submit">Submit</button>
}

控制器

[HttpPost]
public void SetPermission(DataSharingModels dsm)
{
    //do stuff
}

所以事实证明问题出在我附加的变量上,以便将 html 属性添加到我的复选框。在我看来,我有这样的事情:

nbtcAttr = new {@Name = "NBTC"}

这会覆盖使用 CheckBoxFor 生成的名称,而不是:

@Html.CheckBoxFor(m => m.NBTCGroup.NBTC_FA_Centroid) 
//generates:
//<input name="NBTCGroup.NBTC_FA_Centroid" data-val:"true" data-val-required:"The NBTC_FA_Centroid field is required" id="NBTCGroup_NBTC_FA_Centroid" type="checkbox" value="true">
//<input name="NBTCGroup.NBTC_FA_Centroid" type="hidden" value="false">

你明白了:

@Html.CheckBoxFor(m => m.NBTCGroup.NBTC_FA_Centroid, nbtcAttr)
//generates:
//<input name="NBTC" data-val="true" data-val-required:"The NBTC_FA_Centroid field is required" id="NBTCGroup_NBTC_FA_Centroid" name="NBTCGroup.NBTC_FA_Centroid" type="checkbox" value="true">
//<input name="NBTCGroup.NBTC_FA_Centroid" type="hidden" value="false">

请注意在上一个示例中,true 和 false 生成的复选框的名称不匹配。事实证明,模型绑定过程会查找 name 属性,因此当我更改名称时,它会从隐藏输入中获取 false 值,无论该复选框是否被选中。它只是看到了正确的名称(而 true 值的名称不正确)并将该值绑定到模型。

我所做的不是更改名称,而是添加了一个 class 并使用它来查找我想要的 JS 内容中的元素:

nbtcAttr = new {@class = "NBTC"}