MVC3 集合模型与 EditorFor 绑定
假设我有以下内容:
public class Foo
{
public string Value1 { get; set; }
public string Value2 { get; set; }
}
public class BarViewModel
{
public string Baz { get; set; }
public IList<Foo> Foos { get; set; }
}
我有一个接收 BarViewModel
的视图:
@model BarViewModel
@Html.EditorFor(model => model.Baz)
<table>
@for(int i = 0 ; i < Model.Foos.Count ; i ++)
{
string name1 = "Foos[" + i.ToString() + "].Value1";
string name2 = "Foos[" + i.ToString() + "].Value2";
<tr>
<td>
<input type="text" name="@name1" value="@Model.Foos[i].Value1" />
</td>
<td>
<input type="text" name="@name2" value="@Model.Foos[i].Value2" />
</td>
</tr>
}
</table>
在我的控制器中,我有一个接收 BarViewModel
的 POST 方法。
鉴于为 Value1 和 Value2 生成的输入名称为 "Foos[0].Value1"
和 "Foos[1].Value1"
等等,BarViewModel 上的集合,在POST方法中,由ModelBinder自动填充。惊人的。
问题是,如果我在我的视图中这样做:
@for(int i = 0 ; i < Model.Foos.Count ; i ++)
{
<tr>
<td>
@Html.EditorFor(model => model.Foos[i].Value1);
</td>
<td>
@Html.EditorFor(model => model.Foos[i].Value2);
</td>
</tr>
}
那么为输入生成的名称就像 "Foos__0__Value1"
,并且会破坏模型绑定。我的 POST 方法中 BarViewModel 的 Foos
属性现在为 null
我遗漏了什么?
编辑
如果我在集合本身上使用 EditorFor
:
@EditorFor(model => model.Foos)
名称会正确生成。但这迫使我在 /Views/Share 中构建一个 ViewModel 来处理 Foos 类型,这将生成行,但我真的不想这样做......
编辑 2
我将在这里澄清我的问题,我理解这有点含糊。
如果我这样做:
@EditorFor(model => model.Foos)
输入的名称将采用 "Foos[0].Value1"
形式,并且模型绑定在帖子上工作得很好。
但如果我这样做:
@for(int i = 0 ; i < Model.Foos.Count ; i ++)
{
@EditorFor(model => Model.Foos[0].Value1)
}
名称采用 "Foos__0__Value1"
形式,并且模型绑定不起作用。在我的 post 方法中, model.Foos 将为 null。
第二种语法破坏模型绑定是否有原因?
Regarding this post and this other one.
Suppose I have the following:
public class Foo
{
public string Value1 { get; set; }
public string Value2 { get; set; }
}
public class BarViewModel
{
public string Baz { get; set; }
public IList<Foo> Foos { get; set; }
}
And I have a view that receive a BarViewModel
:
@model BarViewModel
@Html.EditorFor(model => model.Baz)
<table>
@for(int i = 0 ; i < Model.Foos.Count ; i ++)
{
string name1 = "Foos[" + i.ToString() + "].Value1";
string name2 = "Foos[" + i.ToString() + "].Value2";
<tr>
<td>
<input type="text" name="@name1" value="@Model.Foos[i].Value1" />
</td>
<td>
<input type="text" name="@name2" value="@Model.Foos[i].Value2" />
</td>
</tr>
}
</table>
And in my controller I have a POST method that recive the BarViewModel
.
Given the inputs names generated for Value1 and Value2 are "Foos[0].Value1"
and "Foos[1].Value1"
and so on, the collection on the BarViewModel, in the POST method, is automatically filled by the ModelBinder. Awesome.
The problem is, if I do it this way in my view :
@for(int i = 0 ; i < Model.Foos.Count ; i ++)
{
<tr>
<td>
@Html.EditorFor(model => model.Foos[i].Value1);
</td>
<td>
@Html.EditorFor(model => model.Foos[i].Value2);
</td>
</tr>
}
Then the names generated for the input are like "Foos__0__Value1"
, and that break the model binding. The Foos
property of my BarViewModel, in my POST method, is now null
I am missing something?
Edit
If I use EditorFor
on the collection itself:
@EditorFor(model => model.Foos)
The names are generated correctly. But that force me to build a ViewModel in /Views/Share to handle the type Foos
, that will generate the row, wich I dont really want to do...
Edit 2
I will clarify my question here, I understand that it's a bit vague.
If I do :
@EditorFor(model => model.Foos)
The names of the inputs will have the form "Foos[0].Value1"
and the model binding works just fine on posts.
But if I do :
@for(int i = 0 ; i < Model.Foos.Count ; i ++)
{
@EditorFor(model => Model.Foos[0].Value1)
}
The names takes the form "Foos__0__Value1"
and the model binding does not works. On my post method, model.Foos will be null.
Is there a reason why the second syntax breaks the model binding?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不完全确定你的问题是什么。然而,这就是 MVC 的工作原理。 EditorFor 使用 EditorTemplates,并且您可以为您的类型定义编辑器模板。它不必进入共享,它可以进入您正在使用的任何级别。例如,您可以将其放在 /Views/Home/EditorTemplates/Foos.cshtml 中,只要您不在 Home 控制器以外的任何地方使用它即可。
I'm not entirely sure just exactly what your question is. However, this is how MVC works. EditorFor uses EditorTemplates, and you define an editor template for your type. It doesn't have to go in Share, it can go in whatever level you're using. For instance, you can have it at /Views/Home/EditorTemplates/Foos.cshtml, so long as you aren't using it anywhere other than your Home controller.