Свойство IEnumerable модели в шаблоне редактора ASP.NET MVC 3
У меня есть модель, которая имеет свойство IEnumerable (предупреждение псевдокода, чтобы следовать)
public class PersonModel {
public string Name { get; set; }
public IEnumerable<AddressModel> Addresses { get; set; }
}
public class AddressModel {
public string Name { get; set; }
}
Я хочу отобразить подобъекты Address в том же виде
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>
Чудесно, все отлично работает
Но, будучи мерзавцем, я теперь хочу начать использовать Шаблоны Макетов, чтобы обернуть все мои свойства стандартным способом и прочее.
Поэтому для этого я создаю string.cshtml и list.cshtml с _Control.cshtml для макета.
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)
(пока да! но подождите.. о нет..)
Вот беда
<ul>@Html.EditorFor(m=>m.Addresses)</ul>
с основного вида (см. выше) становится
@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>
Это неверно отображает идентификатор и имена, что-то вроде Addresses_item_Name, которое не содержит идентификатор, поэтому добавление идентификатора с помощью цикла for
@for (var i = 0; i < Model.Count();i++ ) {
@Html.EditorFor(m => Model.ElementAt(i))
}
Это взрывается, поскольку помощник выражений MVC не допускает ничего, кроме массивов, но адреса должны быть IEnumerable<>, потому что EF4.1 не поддерживает.ToArray внутри подзапроса, т.е.
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();
Кто-нибудь сталкивался с этим? Есть ли стандартный способ сделать это?
Это работает, но так ли это?
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>
Желаемая структура
<form>
<control>
Person Name Control Elements
<control>
<control>
Address List Control Elements
<control>
</form>
1 ответ
EditorFor не позволяет ничего помещать в свойства, а не в методы, поэтому он умирает.
Мой совет - создать шаблон как отдельный элемент адреса, затем использовать цикл снаружи для редактирования каждого элемента или использовать editorformodel, который сделает это за вас.
си