Ajax.BeginForm Post 无法在 PartialView 中绑定对象列表

Ajax.BeginForm Post not able to bind a list of objects within a PartialView

我正在尝试设置一个显示对象列表的 PartialView,其中包含最终用户将勾选的布尔值 属性。提交后,PartialView 应执行 AJAX POST 以便将该对象列表传递给另一个 PartialViewResult 并在同一页面上显示另一个 PartialView。

但是,我的控制器正在为该列表获取空值。我该如何解决这个问题?

简单示例:

查看:

<div id="divNumOne">
     <!-- Where the first PartialView is Displayed -->
</div>
<div id="divNumTwo">
     <!-- Where the second PartialView should be Displayed -->
</div>

PartialViewOne:

@model MyApplicationName.Models.SearchList

<script src="~/Scripts/jquery-3.3.1.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>

@{using (Ajax.BeginForm("PartialView2", "ControllerName", null, new AjaxOptions()
{
     HttpMethod = "POST",
     UpdateTargetId = "divNumTwo",
     InsertionMode = InsertionMode.Replace
}, new
{
     id = "partialViewOneSubmitForm"
}))
{
     @Html.AntiForgeryToken()
     <table>
          <thead>
               <tr>
                    <th>Select</th>
                    <th>ColumnOne</th>
                    <th>ColumnTwo</th>
                    <!-- etc. ... -->
               </tr>
          </thead>
          <tbody>
          @foreach (var item in Model.SearchResultList)
          {
               <tr>
                    <td>
                         @Html.CheckBoxFor(modelItem => item.Select)
                    </td>
                    <td>
                         @Html.DisplayFor(modelItem => item.ColumnOne)
                         @Html.HiddenFor(modelItem => item.ColumnOne)
                    </td>
                    <td>
                         @Html.DisplayFor(modelItem => item.ColumnTwo)
                         @Html.HiddenFor(modelItem => item.ColumnTwo)
                    </td>
                    <!-- etc. ... -->
               </tr>
          }
          </tbody>

<!-- etc. ... -->

<button type="submit" class="btn btn-outline-primary" style="font-weight:500;">Lock in</button>

型号:

public class SearchList
{
     public List<SearchResult> SearchResultList { get; set; }
}

public class SearchResult
{
     public bool Select { get; set; }
     public string ColumnOne { get; set; }
     public string ColumnTwo { get; set; }
     // etc. ...
}

MVC 非常注重其模型与列表的绑定。它使用在 lambda 表达式中传递的变量名称设置为每个表单元素的 name 属性,然后在传递回控制器时尝试将这些变量与模型匹配。如果检查每个元素,您可能会看到列表中每个项目的 name="item.Select"name="item.ColumnOne"name="item.ColumnTwo"。这意味着控制器无法区分它们,因此没有完成绑定。

修复:使用 for 循环而不是 foreach 循环。

@for (var i = 0; i < Model.SearchResultList.Count; i++) // might need to be .Length or .Count() depending on the type of SearchResultList
{
    <tr>
        <td>
            @Html.CheckBoxFor(modelItem => Model.SearchResultList[i].Select)
        </td>
        <td>
            @Html.DisplayFor(modelItem => Model.SearchResultList[i].ColumnOne)
            @Html.HiddenFor(modelItem => Model.SearchResultList[i].ColumnOne)
        </td>
        <td>
            @Html.DisplayFor(modelItem => Model.SearchResultList[i].ColumnTwo)
            @Html.HiddenFor(modelItem => Model.SearchResultList[i].ColumnTwo)
        </td>
        <!-- etc. ... -->
    </tr>
}

这允许控制器在 POST 上正确建模绑定。