tag net mvc for asp asp.net-mvc-3 razor editortemplates

asp.net mvc 3 - net - Problema con MVC EditorPara la plantilla nombrada



select asp-for asp-items (3)

Tengo lo que parece (para mí de todos modos) ser un problema extraño ...

Creé una plantilla de editor simple para un SelectListItem (SelectListItem.cshtml en la carpeta ~ / Views / Shared / EditorTemplates), por ejemplo:

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

Donde c.Categories es un IEnumerable

Esto funcionó bien, pero quería otra plantilla para representar la colección con un marcado ligeramente diferente, así que copié y cambié el nombre de la plantilla del editor a, por ejemplo, ''CategoryIcons.cshtm'' e invocé de la siguiente manera:

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

En resumen, la única diferencia es que estoy especificando una plantilla de editor con nombre.

Cuando abro la página, ahora aparece el siguiente error:

El elemento del modelo que se pasa al diccionario es del tipo ''System.Collections.Generic.List`1 [System.Web.Mvc.SelectListItem]'', pero este diccionario requiere un elemento del modelo ''System.Web.Mvc.SelectListItem''

La declaración del modelo de la plantilla, en ambas plantillas id:

@model System.Web.Mvc.SelectListItem

No entiendo por qué la plantilla predeterminada funciona y la plantilla nombrada no. Cualquier ayuda sería apreciada.

Gracias.


Cuando llama a @Html.EditorFor(c => c.Categories) , vuelve a la plantilla predeterminada para IEnumerable. Esta plantilla predeterminada la proporciona el marco MVC, y su comportamiento es generar Html.EditorFor() para cada elemento de la enumeración. A su vez, esto emite la plantilla de editor apropiada para cada elemento en la lista individualmente, en su caso, todas son instancias de SelectListItem , por lo que en el primer caso, la plantilla SelectListItem se usa para cada elemento.

En el segundo caso, al configurar explícitamente su EditorFor para usar una plantilla de editor particular, CategoryIcons , le está diciendo que use esa plantilla de editor para toda la enumeración , en lugar de permitir que el número sea una plantilla por defecto, a su vez usa la plantilla para cada plantilla. artículo enumerado.

No estoy seguro de la mejor manera de evitar esto todavía.

Un enfoque sería definir una plantilla de CategoryIcons , cuyo modelo es una instancia de IEnumerable<CategoryIcon> , que simplemente busca la enumeración del Model y realiza Html.EditorFor para cada elemento, con una referencia de plantilla explícita de CategoryIcon . Luego coloca su plantilla de editor por artículo en esa plantilla ( CategoryIcon no CategoryIcons ). Luego llamará a esto haciendo @Html.EditorFor(c => c.Categories, "CategoryIcons") .

Voy a echar un vistazo para ver si hay mejores maneras de hacer esto, pero espero que esto sea útil por ahora. Sería genial si las plantillas pudieran parametrizarse, por lo que podría escribir una plantilla IEnumerable que tome como argumento el nombre de la plantilla que se usará para cada uno de sus elementos.


Sólo una actualización, me topé con esta pregunta tratando de abordar el mismo problema yo mismo.

Lo que terminé haciendo fue iterando a través de cada instancia de la colección y llamando a EdtorFor individualmente, algo así:

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

Aún no está limpio, pero me gusta más que heredar una nueva clase como la que terminaste haciendo.

(Lo siento si mi sintaxis de C # está un poco apagada, escribo en vb.net)


Si está utilizando EditorFor, no creo que la solución de bucle funcione. Parece que el uso de la plantilla IEnumerable es la única forma para que las entradas de formulario se nombren correctamente; Si solo llama a EditorFor repetidamente, entonces sus formularios <INPUT> s tendrán la misma ID, en lugar de las ID indexadas.

Experimenté este problema y la solution fue emitir la plantilla enumerable y no recorrer los elementos de la lista.

Lamento hacer de esto una respuesta, no un comentario, no tengo derechos para comentar.