超文本标记语言BeginForm不返回全部数据

本文关键字:全部 数据 返回 BeginForm 超文本标记语言 | 更新日期: 2023-09-27 18:13:51

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

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

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

做一些排序并将List传递给我的视图:

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条记录(有10确实为这个ContentTypeId)

如果我把视图做成这样:

<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)返回到我的控制器-没有任何丢失。

这是非常混乱的-我正在与一个单一的实体工作,只是检查不同的属性值,每次得到不同的结果。如果我不执行任何检查,那么我就会得到所有东西……是什么导致了这个…div ?

请阅读这篇博客,特别是关于跳过数组索引的部分,以及当这种情况发生时会发生什么。

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

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

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

超文本标记语言BeginForm不返回全部数据

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

请参阅Phil hackack的博客:

<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:当你确保你传递的模型是你想要显示的模型时,你就不会有这个问题;当重新订购视图模型客户端然后将其发布回来时,我自己遇到了这个问题。