asp.net-mvc MVC - 编辑对象列表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12696988/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 02:18:52  来源:igfitidea点击:

MVC - Editing a list of objects

asp.net-mvchttp-post

提问by DMCApps

I have the following class layout in MVC:

我在 MVC 中有以下类布局:

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

now I create a strongly typed view in MVC of this type and make editable text fields to edit each value as well as use a foreach loop to populate text fields to edit the items in the list of someitem.

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

when I submit to the httppost method the singular values come back fine in the reportmodel object but the list does not get returned in the object. How should this be done?

当我提交给 httppost 方法时,奇异值在 reportmodel 对象中恢复正常,但列表没有在对象中返回。这应该怎么做?

When I say httppost I am referring to the method that MVC is posting back to

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

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

View code for posting the list of 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>
    }
}

回答by Darin Dimitrov

Don't use ElementAt(1)in your lambda expressions => this ruins your input field names. Please read the blog post that Kirill suggested you.

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

So you could use indexed access:

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

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>
}

Of course in order to have indexer access to the collection this assumes that your itemsproperty is declared as either List<SomeItem>or SomeItem[]. If it is an IEnumerable<SomeItem>it won't work. So simply change the type of this property on your view model.

当然,为了让索引器访问集合,这假定您的items属性被声明为List<SomeItem>or 或SomeItem[]。如果它是一个IEnumerable<SomeItem>它不会工作。因此,只需在您的视图模型上更改此属性的类型。

回答by Erik Funkenbusch

Kirill's reference to Scott Hanselman's blog entry is correct, but you're reading it too narrowly. In the example shown, he passes the array to the action method, but it could just as easily be contained within the parent model as well. The same concept applies.

Kirill 对 Scott Hanselman 博客条目的引用是正确的,但您的阅读范围太窄了。在显示的示例中,他将数组传递给 action 方法,但它也可以很容易地包含在父模型中。同样的概念也适用。

However, one thing to know is that the default model binder does not instantiate nested classes, so it will not create an instance of the List class, which means it will always be null. To fix this, you must instantiate the empty list class in the constructor.

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

This is only part of the problem, though as the data must be formatted in the correct way for the model binder to bind it. This is where Scott's blog post comes in, as it provides the format needed for the model binder to recognize the data as a list.

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

This is typically handled for you if you use an EditorTemplate and use Html.EditorFor(m => m.Items) and then have a SomeItem.cshtml EditorTemplate. This deals with the issues of collection item naming (so long as you also use strongly typed helpers in the template as well).

如果您使用 EditorTemplate 并使用 Html.EditorFor(m => m.Items) 然后使用 SomeItem.cshtml EditorTemplate,这通常会为您处理。这处理了集合项命名的问题(只要您还在模板中使用强类型助手)。