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
Asp:net MVC 3: @Html.EditorFor a subcollection of my model in a template?
提问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):


- 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);

