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

问题描述 投票:0回答:1

我正在尝试设置一个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. ...
}
asp.net-mvc asp.net-ajax unobtrusive-ajax
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上正确建模绑定。

© www.soinside.com 2019 - 2024. All rights reserved.