0

我正在尝试设置一个显示对象列表的 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>

部分视图一:

@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. ...
}
4

1 回答 1

1

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 上正确建模绑定。

于 2019-12-19T15:27:06.760 回答