Suppose I have a view typed to a collection, e.g. a List
:
@model List
@for(int i = 0; i < Model.Co
Why does
NameFor
(and thereforeEditorFor
) exhibit this behaviour in this particular scenario when it works fine for slight variations (i.e. is it intentional and, if so, why)?
It is a bug (link) and it will be fixed with release of ASP.NET MVC 5.
Is there a simple way of working around this behaviour without any of the shortcomings of the above?
Simple:
Add ItemViewModel.cshtml
editor template with following code:
@model ItemViewModel
@Html.EditorFor(m => m.Foo)
@Html.EditorFor(m => m.Bar)
Remove _ItemView.cshtml
editor template.
[UIHint("_ItemView")]
attribute from WrappingViewModel
.A little bit harder:
Add ItemViewModel.cshtml
editor template (same as above).
Modify _ItemView.cshtml
:
@model List
@{
string oldPrefix = ViewData.TemplateInfo.HtmlFieldPrefix;
try
{
ViewData.TemplateInfo.HtmlFieldPrefix = string.Empty;
for (int i = 0; i < Model.Count; i++)
{
var item = Model[i];
string itemPrefix = string.Format("{0}[{1}]", oldPrefix, i.ToString(CultureInfo.InvariantCulture));
@Html.EditorFor(m => item, null, itemPrefix)
}
}
finally
{
ViewData.TemplateInfo.HtmlFieldPrefix = oldPrefix;
}
}
UPDATE
In case if you don't want to add ItemViewModel.cshtml
editor template for the second option then instead of @Html.EditorFor(m => item, null, itemPrefix)
you have to write something like that:
@Html.EditorFor(m => item.Foo, null, Html.NameFor(m => item.Foo).ToString().Replace("item", itemPrefix))
@Html.EditorFor(m => item.Bar, null, Html.NameFor(m => item.Bar).ToString().Replace("item", itemPrefix))
NOTE: It's better to wrap that piece of code as extension method