Свойство IEnumerable модели в шаблоне редактора ASP.NET MVC 3 - PullRequest
4 голосов
/ 27 апреля 2011

У меня есть модель, которая имеет свойство 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>

Чудесно, все отлично работает

Но теперь я хочу начать использовать Template Layouts, чтобы обернуть все мои свойства стандартным шрифтом и прочее

Поэтому для этого я создаю 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 Ответ

2 голосов
/ 22 августа 2012

EditorFor не разрешает помещать типы свойств, а не методы, поэтому он умирает.

Мой совет - создать шаблон как отдельный элемент адреса, а затем использовать цикл внеотредактируйте каждый или используйте editorformodel, который сделает это за вас.

Si

...