1

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

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

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)返回到我的控制器-什么都没有。

这非常令人困惑 - 我正在使用一个实体,只是检查不同的属性值并每次都得到不同的结果。如果我根本不执行任何检查,那么我会拿回所有东西......这可能是什么原因......?

4

2 回答 2

3

请查看此博客,特别是有关跳过数组索引以及发生这种情况时会发生什么的部分。

基本上,因为您只呈现集合中的一些项目,模型绑定由于缺少索引而失败。正如我在对您的另一个问题的评论中所说的那样,将逻辑从视图中删除(无论如何它都不属于)会更好地为您服务。

创建一个 ViewModel,它只是一个简单的类。在该 ViewModel 中,为要显示的每个集合定义属性。在控制器中,将大集合拆分为较小的集合,并将它们分配给 ViewModel 中的属性。将 ViewModel 传递给 View 并编写非常简单的代码来显示其中包含的数据。

完成后,您视图中的循环将与上一个示例完全相同,并且一切都会正常工作。

于 2013-05-16T16:55:08.287 回答
2

这是因为索引字段。您的列表可以工作,但 ModelBinder 在索引中的第一个间隙处停止。

请参阅Phil Haacked 的博客了解如何解决它:

<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未发布您在 index 处的列表项,则(例如)下一个(例如1)将在 index 处0,但我看到您的Id字段会处理这一点。

话虽如此,我确实同意@Jason:当您确保您传递的模型是您要显示的模型时,您不会遇到这个问题;在重新订购视图模型客户端然后将其发回时,我自己遇到了这个问题。

于 2013-05-16T16:54:53.630 回答