CheckBoxFor Html helper 的隐藏字段问题与 serializeArray

CheckBoxFor Html helper's hidden field issue with serializeArray

我有这样的表格。

<form id="myForm">
    <div>
        <ul>
            <li>
                @Html.DropDownListFor(m => m.SelectedVal, new SelectList(Model.ValLst, "Value", "Name"))
            </li>
            <li>
                @Html.TextBoxFor(m => m.Id)
            </li>
            <li>
                @Html.CheckBoxFor(m => m.IsPaid, new { @Id = "IsPaid"})
            </li>
        </ul>           
    </div>
</form>

我必须按如下方式序列化此表单并且我正在对序列化数组进行操作

values = $('#myForm').serializeArray();

0: Object
name: "SelectedVal"
value: "BMV"

1: Object
name: "Id"
value: "123"

2: Object
name: "IsPaid"
value: "true"

3: Object
name: "IsPaid"
value: "false"

我遇到了 CheckBoxFor 助手的问题。因为,它正在创建一个值为 false 的隐藏字段,并且隐藏字段和复选框都具有相同的 ID。因此,复选框的模型值始终为 false,即使它已被选中。即在对序列化数组进行操作时,隐藏字段值会覆盖复选框值。

所以我想到了在序列化时忽略隐藏域。喜欢:

values = $('#myForm').find("input[type != 'hidden']").serializeArray();

0: Object
name: "Id"
value: "123"

1: Object
name: "IsPaid"
value: "true"

但是,它不起作用,因为我没有获得下拉值。于是,想到,DropDownListFor也用到了hidden field。任何建议,如何将正确的复选框值发送到控制器。某些东西,例如忽略复选框或任何其他 html 助手之后的直接隐藏字段,或强制在复选框之前呈现隐藏字段。

我错过了 select 元素。应该是

values = $('#myForm').find('input, select').not(':hidden').serializeArray();

您需要使用 $('#myForm').serialize();,而不是 $('#myForm').serializeArray();

.serializeArray() 是 post 返回 IsPaid=[true, false],即不能绑定到 boolean 属性 的值数组(它与使用隐藏的输入覆盖复选框),其中 .serialize() 将 post IsPaid=true&IsPaid=false 正确绑定到您的模型(DefaulModelBinder 读取第一个值(true) 并忽略任何具有相同名称的后续 name/value 对。

旁注:@Html.DropDownListFor() 不生成隐藏输入。 @Html.CheckBoxFor() 生成的隐藏输入没有 id 属性,new { @Id = "IsPaid"} 毫无意义。助手已经生成 id

复选框始终保持值为 true,而隐藏字段始终保持为 false。但是,对于选中的复选框,它的父跨度包含 class "checked"。因此,在序列化之前,我们可以将所需的值保留在隐藏字段中。现在,让它覆盖。如果parent span有class 'checked',则在相应的隐藏字段中保留'true',否则为false.

        // traverse through all the checkboxes, check class of it's parent span

        $("input[type='checkbox']").each(function () {
            // id of hidden field is same as that of the check box
            var hdnFldId = "input[type='hidden']#" + $(this).attr('id');
            if ($(this).parent().hasClass('checked'))
            {
                $(hdnFldId).val(true);
            }
            else {
                $(hdnFldId).val(false);
            }
        });
        values = $('#myForm').serializeArray();