C# Asp:net MVC 3: @Html.EditorFor 我的模型在模板中的一个子集合?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9125809/
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-08-09 06:05:18  来源:igfitidea点击:

Asp:net MVC 3: @Html.EditorFor a subcollection of my model in a template?

c#.netasp.net-mvcasp.net-mvc-3partial-views

提问by J4N

I've been stuck a long time to edit a subcollection of my model, the collection of the model was coming null.

我被困了很长时间来编辑我的模型的子集合,模型的集合变为空。

I finally found a solution, but I find it a little dirty:

我终于找到了解决方案,但我觉得它有点脏:

First my tests datas:

首先是我的测试数据:

Model object:

模型对象

    public class ContainerObject
    {
        public String Title { get; set; }
        public List<ContainedObject> ObjectList { get; set; }
    }

Sub collection object:

子集合对象

public class ContainedObject
{
    public int Id { get; set; }
    public String Text { get; set; }
    public Boolean IsSelected { get; set; }
}

Controller method which generate the object

生成对象的控制器方法

    public ActionResult TestForm()
    {
        return View(new ContainerObject()
        {
            Title = "This is a sample title",
            ObjectList = new List<ContainedObject>()
                {
                    new ContainedObject(){Id=1, IsSelected = true, Text="ObjectOne"},
                    new ContainedObject(){Id=2, IsSelected = false, Text="ObjectTwo"},
                    new ContainedObject(){Id=3, IsSelected = true, Text="ObjectThree"},
                    new ContainedObject(){Id=4, IsSelected = false, Text="ObjectFour"},
                }
        });
    }

Controller which receive the edited object

接收编辑对象的控制器

    [HttpPost]
    public ActionResult TestFormResult(ContainerObject filledObject)
    {
        return View();
    }

The view

风景

@model WebTestApplication.Models.ContainerObject

@{
    ViewBag.Title = "TestForm";
}
@using (Html.BeginForm("TestFormResult","Home", FormMethod.Post)){
    @Html.EditorFor(x => x.Title)
    Html.RenderPartial("ContainedObject", Model.ObjectList);
    <input type="submit"  value="Submit"/>
}

The partial view(ContainedObject.cshtml)

局部视图(ContainedObject.cshtml)

@model IEnumerable<WebTestApplication.Models.ContainedObject>
@{
    ViewBag.Title = "ContainedObject";
    int i = 0;
}
@foreach (WebTestApplication.Models.ContainedObject currentObject in Model)
{ 
    <br />
    @Html.Label(currentObject.Text);
    @Html.CheckBox("ObjectList[" + i + "].IsSelected", currentObject.IsSelected);                                                                                                     
    @Html.Hidden("ObjectList[" + i + "].Id", currentObject.Id);                                                                                                
    @Html.Hidden("ObjectList[" + i + "].Text", currentObject.Text);
    i++;
}

This is actually working, but I've one problem:

这实际上是有效的,但我有一个问题:

  • I've to generate names myself and specify the property of the container object
  • 我必须自己生成名称并指定容器对象的属性

I tried to use Html.EditorForinstead of Html.RenderPartialin the view, the problem is that it generate me the name "ObjectList.[0].Id"(with a additional . between the property name and the accessor).

我试图使用Html.EditorFor而不是Html.RenderPartial在视图中,问题是它为我生成了名称“ObjectList.[0].Id”(在属性名称和访问器之间有一个额外的 .)。

I also tried to use only @Html.EditorFor in the partial view, but it create vars with the name of the object.

我还尝试在局部视图中仅使用 @Html.EditorFor,但它会创建带有对象名称的变量。

If I don't use any template, it works:

如果我不使用任何模板,它的工作原理:

    @model WebTestApplication.Models.ContainerObject

@{
    ViewBag.Title = "TestForm";
}
@using (Html.BeginForm("TestFormResult", "Home", FormMethod.Post))
{
    @Html.EditorFor(x => x.Title)
    for (int i = 0; i < Model.ObjectList.Count; i++)
    {
        <br />
        @Html.Label(Model.ObjectList[i].Text);
        @Html.CheckBoxFor(m => Model.ObjectList[i].IsSelected);
        @Html.HiddenFor(m => Model.ObjectList[i].Id);
        @Html.HiddenFor(m => Model.ObjectList[i].Text);
    }

    <br /><input type="submit"  value="Submit"/>
}

But here it's a simple template, but in my real case, I will have much more data, and this will be re-used multiple time. So what is my best option?

但这里是一个简单的模板,但在我的真实案例中,我将拥有更多数据,并且会多次重复使用。那么我最好的选择是什么?

采纳答案by Denis Ivin

You can simplify your code by introducing the EditorTemplate. Here is how:

您可以通过引入 EditorTemplate 来简化代码。方法如下:

  • The main view remains pretty much the same except we replaced RenderPartial with EditorFor:
  • 除了我们用 EditorFor 替换了 RenderPartial 之外,主视图几乎保持不变:

TestForm.cshtml

测试表格.cshtml

@model WebTestApplication.Models.ContainerObject

@{
    ViewBag.Title = "TestForm";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

@using (Html.BeginForm("TestFormResult", "Home", FormMethod.Post)) {
    @Html.EditorFor(m => m.Title)
    @Html.EditorFor(m => m.ObjectList);

    <input type="submit" value="Submit" />
}
  • Then create a folder named EditorTemplatesunder Views/Home(assuming your controller is Home):
  • 然后在Views/Home下创建一个名为EditorTemplates的文件夹(假设你的控制器是 Home):

enter image description here

在此处输入图片说明

  • and add the following template for the ContainedObject:
  • 并为ContainedObject添加以下模板:

ContainedObject.cshtml

包含对象.cshtml

@model WebTestApplication.Models.ContainedObject

<p>
    @Html.DisplayFor(m => m.Text)
    @Html.CheckBoxFor(m => m.IsSelected)
    @Html.HiddenFor(m => m.Id)
    @Html.HiddenFor(m => m.Text)
</p>

The editor will automatically iterate through the list of objects rendering the view for each of them. Hope it helps.

编辑器将自动遍历对象列表,为每个对象呈现视图。希望能帮助到你。

回答by Tom Gerken

I found this thread while looking for something else related. Denis has the correct answer, but I thought I would add some syntax in case anyone else comes across this:

我在寻找其他相关内容时发现了这个线程。Denis 有正确的答案,但我想我会添加一些语法,以防其他人遇到这个:

If you have an editor template named "SomeTemplate.cshtml" you can use it for a list of Item as follows in your view:

如果您有一个名为“SomeTemplate.cshtml”的编辑器模板,您可以将其用于视图中的 Item 列表,如下所示:

@for (var i = 0; i < Model.ObjectList.Count(); i++)
{
    @Html.EditorFor(m => m.ObjectList[i], "SomeTemplate")
}

Then in your editor template:

然后在您的编辑器模板中:

@model WebTestApplication.Models.ContainedObject

<br />
@Html.Label(Model.Text);
@Html.CheckBoxFor(m => m.IsSelected);
@Html.HiddenFor(m => m.Id);
@Html.HiddenFor(m => m.Text);