Domanda

Non ho quello che sembra (a me comunque) di essere uno strano problema ...

Ho creato un modello di editor di semplice per un SelectListItem (SelectListItem.cshtml in ~ / Vista / Shared / EditorTemplates cartella), per esempio:

<ul class="select-list-item cell-15 col-3 omega clearfix">
    @Html.EditorFor(c => c.Categories)
</ul>

Dove c.Categories è un IEnumerable

Questo bene ha funzionato, ma ho voluto un altro modello per rendere la collezione con un po 'diverso di markup, così ho copiato e rinominato l'editor di modelli, per esempio, 'CategoryIcons.cshtm' e invocato come segue:

<ul class="select-list-item cell-15 col-3 omega clearfix">
    @Html.EditorFor(c => c.Categories, "CategoryIcons")
</ul>

In breve, l'unica differenza è che sto specificando un editor di modelli di nome.

Quando ho aperto la pagina, ora ottengo il seguente errore:

La voce del modello passato nel dizionario è di tipo 'System.Collections.Generic.List`1 [System.Web.Mvc.SelectListItem]', ma questo dizionario richiede un elemento del modello di tipo 'System.Web.Mvc. SelectListItem '

Il modello di dichiarazione del modello, sia in modelli ID:

@model System.Web.Mvc.SelectListItem

Non capisco il motivo per cui il modello predefinito funziona e il modello di nome non lo fa. Qualsiasi aiuto sarebbe apprezzato.

Grazie.

È stato utile?

Soluzione

When you call @Html.EditorFor(c => c.Categories) it is falling back to the default template for IEnumerable. This default template is provided by the MVC framework, and its behaviour is to output Html.EditorFor() for each item in the enumeration. That in turn emits the appropriate editor template for each item in the list individually - in your case they're all instances of SelectListItem, so in the first case, the SelectListItem template is used for each item.

In the second case, by explicitly setting your EditorFor to use a particular editor template CategoryIcons, you are telling it to use that editor template for the whole enumeration, instead of allowing the enumerable to be templated by default, in turn using the template for each enumerated item.

I'm not sure of the best way around this just yet.

One approach would be to define a CategoryIcons template, whose model is an instance of IEnumerable<CategoryIcon>, which simply foreaches the Model enumeration, and performs Html.EditorFor for each item, with an explicit template reference of CategoryIcon. You then put your per-item editor template in that template (CategoryIcon not CategoryIcons). You would then call this by doing @Html.EditorFor(c => c.Categories, "CategoryIcons").

I'm going to have a look around to see if there are better ways to get this done, but I hope this might be useful for now. It would be great if templates could be parameterized, so you could write an IEnumerable template that takes as an argument the name of the template to use for each of its items.

Altri suggerimenti

Just an update, I stumbled on this question trying to address the same issue myself.

What I ended up doing was iterating through each instance of the collection and calling the EdtorFor individually, sort of like this:

<ul class="select-list-item cell-15 col-3 omega clearfix">
    @for (int i=0;i<Model.Categories.Count;i++) {
        @Html.EditorFor(c => c.Categories[i], "CategoryIcons")
    }
</ul>

Still not clean, but I like it better than inheriting a new class like you ended up doing.

(Sorry if my C# syntax is a little off, I write in vb.net)

If you're using EditorFor, I don't think the looping solution will work. It seems that using the IEnumerable template is the only way for the form inputs to be named correctly; if you just call EditorFor repeatedly, then your form <INPUT>s will have the same ID, rather than indexed IDs.

I experienced this issue and the solution was to emit the enumerable template and not loop through the list items.

Sorry to make this an answer not a comment -- don't have commenting rights.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top