IEnumerable model property in ASP.NET MVC 3 editor template

I have a model that has the IEnumerable property (warning pseudocode)

public class PersonModel { public string Name { get; set; } public IEnumerable<AddressModel> Addresses { get; set; } } public class AddressModel { public string Name { get; set; } } 

I want to display Address sub-objects in the same view

Person.cshtml

 @model PersonModel <form> <h2>Person</h2> @Html.EditorFor(m=>m.Name) <ul>@Html.EditorFor(m=>m.Addresses)</ul> </form> 

EditorTemplate / AddressModel

 @model AddressModel <li>@Html.TextboxFor(m=>m.Name)</li> 

Great, everything works great

But, being git, now I want to start using template templates to wrap all my properties with a standard type, etc.

So, I create string.cshtml and list.cshtml for this, using _Control.cshtml for the layout

EditorTemplates / _Control.cshtml

 <div> @Html.Label(string.Empty) <div class="input"> @RenderBody() @Html.ValidationMessage(string.Empty) </div> </div> 

EditorTemplates / string.cshtml

 @model string @{ Layout = "_Control.cshtml"; } @Html.TextBox(string.Empty, Model) 

(still yay !, but wait .. oh no ..)

Here is the problem

 <ul>@Html.EditorFor(m=>m.Addresses)</ul> 

from the main view (see above) becomes

 @Html.EditorFor(m=>m.Addresses, "List") 

EditorTemplates / list.cshtml

 @model IEnumerable<object> @{ Layout = "_Control.cshtml"; } <ul> @foreach(var item in Model){ @Html.EditorFor(m => item) } </ul> 

This incorrectly displays the identifier and names, for example Addresses_item_Name, which does not contain the identifier, so adding an identifier with a for loop

 @for (var i = 0; i < Model.Count();i++ ) { @Html.EditorFor(m => Model.ElementAt(i)) } 

This explodes because the MVC expression helper allows nothing but arrays, but Addresses must be IEnumerable <> because EF4.1 does not support .ToArray inside a subquery, i.e.

 var model = (from p in DataContext.People where p.Id = 1 select new PersonModel { Name = p.Name, Addresses = (from a in p.Addresses select new AddressModel { Name = a.Name }).ToArray() // **NOT SUPPORTED** }).FirstOrDefault(); 

Has anyone come up with this? Is there a standard way to do this?

It works, but right?

EditorTemplates / list.cshtml

 @model IEnumerable<object> @{ Layout = "_Control.cshtml"; var prefix = ViewData.TemplateInfo.HtmlFieldPrefix; } <ul> @for (var i = 0; i < Model.Count();i++ ) { var item = Model.ElementAt(i); ViewData.TemplateInfo.HtmlFieldPrefix = string.Format("{0}[{1}]",prefix, i); @Html.EditorFor(m => item, null, string.Empty) } </ul> 

Required structure

 <form> <control> Person Name Control Elements <control> <control> Address List Control Elements <control> </form> 
+4
source share
1 answer

The editor does not allow anything to put property types, not methods, it will cause him to die.

My advice would be to create a template as a separate address element, then use a loop outside to edit each one or use an editor that will do this for you.

Si

+2
source

All Articles