IEnumerable modèle de propriété dans un ASP.NET MVC 3 de l'Éditeur de Modèle

J'ai un modèle qui a un IEnumerable propriété (avertissement pseudo-code à suivre)

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

public class AddressModel {
    public string Name { get; set; }
}

Je veux afficher l'Adresse des sous-objets dans la même vue

Personne.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>

Merveilleux, tous fonctionne bien

Mais étant un git, je veux maintenant commencer à utiliser le Modèle Dispositions pour l'emballage de tous mes biens dans un standard de la façon dont le type et les trucs

J'ai donc créer une chaîne de caractères.cshtml et une liste.cshtml pour ce faire, avec un _Control.cshtml pour la mise en page

EditorTemplates/_Control.cshtml

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

        @Html.ValidationMessage(string.Empty)
    </div>
</div>

EditorTemplates/chaîne.cshtml

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

(yay!!! mais attendez.. ah non..)

Voici le problème

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

à partir de l'affichage principal (voir ci-dessus) devient

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

EditorTemplates/liste.cshtml

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

Ce qui rend l'id et les noms de manière incorrecte, quelque chose comme Addresses_item_Name, qui ne contient pas l'Id, donc, l'ajout de l'id avec une boucle for

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

Ce souffle que le MVC expression helper ne pas laisser quoi que ce soit mais les tableaux, mais les Adresses doit être IEnumerable<> parce que EF4.1 ne prend pas en charge .ToArray à l'intérieur d'une sous-requête ie.

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();

A quelqu'un de venir contre cela?
Est il existe des moyen de le faire?

Cela fonctionne, mais est-il bon?

EditorTemplates/liste.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>

La structure désirée est

<form>
    <control>
       Person Name Control Elements
    <control>

    <control>
       Address List Control Elements
    <control>
</form>
Pourquoi avez-vous besoin de cette Liste.cshtml modèle? Ne pouvez pas voir toute la valeur ajoutée, en particulier tout ce que vous faites à l'intérieur est d'écrire une boucle et appeler un autre éditeur de modèle pour chaque élément de la collection qui est déjà fait automatiquement par défaut.
Permet pour le modèle de mise en page
Johnston, mais vous avez déjà compris le modèle de mise en page dans le string.cshtml modèle. Ou vous souhaitez une mise en page différente?
Les adresses de l'ensemble sont enveloppés et non pas de chaque élément, addressmodel.cshtml devrait être textboxfor, je vais corriger ça
OMI, vous feriez mieux de faire un foreach et en incrémentant une variable de compteur séparément. Le Count() et ElementAt() les méthodes sont potentiellement coûteux (en fonction de la liste sous-jacente), mais simplement l'énumération (foreach) sera tout aussi bon, peu importe.

OriginalL'auteur Anthony Johnston | 2011-04-27