我曾问过非常类似的问题,但现在我缩小了外部因素,现在希望有人能够指出我做错了什么以及为什么我没有得到预期的结果。

在我的控制器中,我从数据库中获取数据:

List<MCS_DocumentFields> model = (List<MCS_DocumentFields>)DocumentFieldService.GetFieldsForDocument(documentId);


进行一些排序并将列表传递给我的视图:

var finalModel = model
                .OrderBy(c => c.ContentTypeId)
                .ThenBy(c => c.RowNo)
                .ThenBy(c => c.ColumnNo)
                .ThenBy(c => c.MCS_Fields.Order)
                .ToList();
            return View(finalModel);


此时finalModel的类型为List<MCS_DocumentFields>

我的看法是这样的:

@model List<DataAccess.MCS_DocumentFields>
@{
    ViewBag.Title = "Document";
}
<div id="drawForm">

@using (Html.BeginForm("ActionMethodName", "Forms"))
{
    <table border="1">
        @for (int i = 0; i < Model.Count; i++)
        {
            if (!string.IsNullOrEmpty(Model[i].FieldValue))
            {
                <tr>
                <td>
                @Html.DisplayFor(x => x[i].FieldValue)
                @Html.HiddenFor(x => x[i].FieldValue)
                @Html.HiddenFor(x => x[i].Id)
                </td>
                </tr>
            }
        }
    </table>
   <button type="submit">Submit</button>
}
</div>


这是呈现状态,我在浏览器中看到大约15行数据。当我向控制器提交数据时:

[HttpPost]
public ActionResult ActionMethodName(List<MCS_DocumentFields> collection)
{
    var test = collection;
    //Some other code
}


在视图中使用此特定代码,我从页面上呈现的15条记录中获得了1条记录。

但是,如果我这样改变看法:

<table border="1">
        @for (int i = 0; i < Model.Count; i++)
        {
            if (Model[i].ContentTypeId == 1)
            {
                <tr>
                <td>
                @Html.DisplayFor(x => x[i].FieldValue)
                @Html.HiddenFor(x => x[i].FieldValue)
                @Html.HiddenFor(x => x[i].Id)
                </td>
                </tr>
            }
        }
    </table>


更具体地说-if (Model[i].ContentTypeId == 1)我得到10条记录(此ContentTypeId实际上有10条记录)

如果我做出这样的看法:

<table border="1">
        @for (int i = 0; i < Model.Count; i++)
        {

                <tr>
                <td>
                @Html.DisplayFor(x => x[i].FieldValue)
                @Html.HiddenFor(x => x[i].FieldValue)
                @Html.HiddenFor(x => x[i].Id)
                </td>
                </tr>
        }
    </table>


根本不需要检查,只需遍历所有记录-我将所有记录(43)返回给控制器-没有丢失。

这非常令人困惑-我正在使用一个单一实体,只是检查不同的属性值并每次都获得不同的结果。而且,如果我根本不执行任何检查,那么我将一切退回……是什么原因造成的。

最佳答案

这是由于索引字段。您的列表可以使用,但是ModelBinder停在索引的第一个间隙处。

有关解决方法,请参见Phil Haacked's blog

<input type="hidden" name="products.Index" value="cold" />
<input type="text" name="products[cold].Name" value="Beer" />
<input type="text" name="products[cold].Price" value="7.32" />


您要在cold放置@i。请注意,这将导致发布的列表被折叠:如果您未发布索引为0的列表项,则下一个列表项(例如1)将为索引0,但我看到了Id字段将解决此问题。

话虽如此,我确实同意@Jason的观点:当您确保传递的模型是您要显示的模型时,您将不会遇到此问题;我在重新排序ViewModel客户端然后将其重新发布时遇到了这个问题。

10-05 23:32
查看更多