我正在尝试设置一个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上正确建模绑定。