MVC - 编辑对象列表

时间:2012-10-02 19:31:37

标签: asp.net-mvc http-post

我在MVC中有以下类布局:

public class ReportModel 
{
    List<SomeItem> items;
    string value;
    string anotherValue;
}

现在我在这种类型的MVC中创建一个强类型视图,并使可编辑的文本字段编辑每个值,并使用foreach循环填充文本字段以编辑someitem列表中的项目。

当我提交到httppost方法时,单个值在reportmodel对象中返回正常,但列表不会在对象中返回。该怎么做?

当我说httppost时,我指的是MVC发回的方法

[HttpPost]
public ActionResult EditReport(ReportModel report)
{
    // Save the report in here after the update on the UI side
}

查看发布someitem列表的代码

if (Model.items != null && Model.items.Count > 0)
{
    for (int i = 0; i < Model.items.Count; i++)
    {                
        <div class="editrow">
            <div class="edititem">
                <div class="editor-label">
                    @Html.LabelFor(m => m.items.ElementAt(i).propertyOne)
                </div>
                <div class="editor-field">
                    @Html.TextBoxFor(m => m.items.ElementAt(i).propertyOne)
                    @Html.ValidationMessageFor(m => m.items.ElementAt(i).propertyOne)
                </div>
            </div>
            <div class="edititem">
                <div class="editor-label">
                    @Html.LabelFor(m => m.items.ElementAt(i).propertyTwo)
                </div>
                <div class="editor-field">
                    @Html.TextBoxFor(m => m.items.ElementAt(i).propertyTwo)
                    @Html.ValidationMessageFor(m => m.items.ElementAt(i).propertyTwo)
                </div>
            </div>
            <div class="edititem">
                <div class="editor-label">
                    @Html.LabelFor(m => m.items.ElementAt(i).propertyThree)
                </div>
                <div class="editor-field">
                    @Html.TextBoxFor(m => m.items.ElementAt(i).propertyThree)
                    @Html.ValidationMessageFor(m => m.items.ElementAt(i).propertyThree)
                </div>
            </div>
        </div>
    }
}

2 个答案:

答案 0 :(得分:15)

不要在lambda表达式中使用ElementAt(1) =&gt;这会破坏您输入的字段名称。请阅读Kirill建议你的博客文章。

所以你可以使用索引访问:

for (int i = 0; i < Model.items.Count; i++)
{                
    <div class="editrow">
        <div class="edititem">
            <div class="editor-label">
                @Html.LabelFor(m => m.items[i].propertyOne)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(m => m.items[i].propertyOne)
                @Html.ValidationMessageFor(m => m.items[i].propertyOne)
            </div>
        </div>
        <div class="edititem">
            <div class="editor-label">
                @Html.LabelFor(m => m.items[i].propertyTwo)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(m => m.items[i].propertyTwo)
                @Html.ValidationMessageFor(m => m.items[i].propertyTwo)
            </div>
        </div>
        <div class="edititem">
            <div class="editor-label">
                @Html.LabelFor(m => m.items[i].propertyThree)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(m => m.items[i].propertyThree)
                @Html.ValidationMessageFor(m => m.items[i].propertyThree)
            </div>
        </div>
    </div>
}

当然,为了让索引器访问该集合,我们假设您的items属性被声明为List<SomeItem>SomeItem[]。如果它是IEnumerable<SomeItem>则不起作用。因此,只需在视图模型上更改此属性的类型即可。

答案 1 :(得分:2)

Kirill对Scott Hanselman的博客文章的引用是正确的,但你读得太过狭隘。在所示的示例中,他将数组传递给action方法,但它也可以很容易地包含在父模型中。同样的概念适用。

但是,要知道的一件事是默认模型绑定器不实例化嵌套类,因此它不会创建List类的实例,这意味着它将始终为null。要解决此问题,您必须在构造函数中实例化空列表类。

这只是问题的一部分,但因为数据必须以正确的方式格式化,模型绑定器才能绑定它。这是Scott的博客文章的来源,因为它提供了模型绑定器将数据识别为列表所需的格式。

如果您使用EditorTemplate并使用Html.EditorFor(m =&gt; m.Items)然后使用SomeItem.cshtml EditorTemplate,通常会为您处理。这涉及收集项命名的问题(只要您也在模板中使用强类型帮助程序)。