¿Por qué RazorViewEngine no detecta mi DisplayTemplate?
Frecuentes
Visto 901 veces
7
La aplicación es una aplicación MVC3 con motor de vista RAZOR.
El controlador que se usa aquí es TestController. Estoy usando vistas anidadas.
La vista base (Lista de artículos) es así,
//Listing.cshtml
@model ItemsList
@for (int i = 0; i < Model.Items.Count(); i++)
{
@Html.DisplayFor(x => x.Items[i], new { RowPosition = i})
}
aquí está la plantilla para el artículo
//Item.cshtml
@model Item
@Html.DisplayFor(x=>x.HeaderText)
@Html.DisplayFor(x=>x, "ItemDetails")
Y aquí está la vista de Detalles del artículo
//ItemDetails.cshtml
@model Item
@Html.DisplayFor(x=>x.Description)
Entonces, estoy tratando de pasar el modelo de la plantilla ITEM a la plantilla ITEMDETAILS. ItemDetails.cshtml se coloca en "Views\Test\DisplayTemplates". De hecho, he intentado colocarlo en las carpetas "Vistas\Compartido" y "Vistas\Compartido\DisplayTemplates". Pero View Engine parece no captarlo.
Sin embargo, la documentación de Microsoft aquí indica que el motor de visualización busca en la carpeta Controller\DisplayTemplates para obtener la VISTA utilizando el nombre de plantilla utilizado.
3 Respuestas
6
Este parece ser el comportamiento previsto para Display/EditorTemplates, presumiblemente para evitar la repetición infinita accidental en las plantillas de visualización personalizadas, como hacer (en Item.cshtml
):
@model Item
@Html.DisplayFor(x => x)
...que mostraría infinitamente el Item.cshtml
Plantilla de visualización.
Obviamente, en su ejemplo, está pasando el artículo/modelo a un una experiencia diferente plantilla, por lo que no causaría una recursividad infinita. Sin embargo, todavía parece quedar atrapado por la misma salvaguardia en el marco. ¿No está realmente seguro de si se clasificaría como un 'error' o simplemente 'por diseño'?
Este es el cheque en el Ayudante de DisplayFor/TemplateFor:
// Normally this shouldn't happen, unless someone writes their own custom Object templates which
// don't check to make sure that the object hasn't already been displayed
object visitedObjectsKey = metadata.Model ?? metadata.RealModelType;
if (html.ViewDataContainer.ViewData.TemplateInfo.VisitedObjects.Contains(visitedObjectsKey)) { // DDB #224750
return String.Empty;
}
ViewData.TemplateInfo.VisitedObjects
almacena los objetos/modelos visitados para las plantillas principales. Cuando corres:
@Html.DisplayFor(x => x.Items[i], new { RowPosition = i})
Hace que tu Item.cshtml
DisplayTemplate y agrega el artículo/modelo a VisitedObjects
. Esto significa que cuando Item.cshtml
intenta mostrar otra plantilla secundaria con el mismo artículo/modelo:
@Html.DisplayFor(x => x, "ItemDetails")
El artículo/modelo ya está en VisitedObjects
, por lo que la declaración if anterior devuelve verdadero y en lugar de representar ItemDetails.cshtml
simplemente devuelve/representa silenciosamente una cadena vacía.
contestado el 04 de mayo de 12 a las 00:05
Encontré esta "característica" recientemente y me causó una gran consternación. Creo que el equipo de MVC cometió un error aquí. Devolver una cadena vacía le da al desarrollador la impresión de que todo salió bien, hasta que ve el resultado. También hace que sea casi imposible averiguar qué IS sucediendo. Como mínimo, el código podría generar una excepción, brindando una explicación del comportamiento y alertando al desarrollador sobre el problema. - miguel richardson
1
intenta usar @Html.RenderPartial("ItemDetails", item)
contestado el 03 de mayo de 12 a las 22:05
0
Primero, no uses el bucle for. Display/EditorTemplates son capaces de manejar colecciones.
En segundo lugar, ¿qué es ItemsList? ¿Y cómo se define? Si solo se trata de nombrar un tipo de colección en particular, entonces no lo haga. Solo tenga una Lista o algo en su lugar (a menos que necesite un manejo especial de elementos, en cuyo caso implemente IEnumerable en su clase de colección). Entonces tendría un ItemsList.cshtml o simplemente un Item.cshtml si convierte al uso de una Lista
Además, su DisplayFor() en la vista principal es incorrecta. no puede pasar atributos html a DisplayTemplates de esa manera.
contestado el 03 de mayo de 12 a las 22:05
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas asp.net visual-studio-2010 asp.net-mvc-3 razor or haz tu propia pregunta.
Es probable que no sea un error. Escriba un título más útil/relevante. - user166390
Tom, mi pregunta es por qué el motor de vista no selecciona la Vista. La visualización de ItemDetails solo se muestra en blanco. Sin excepción. ¿Cómo puedo depurar cómo funciona el motor de vista detrás de escena? - EagerToLearn
nunca subestimes el poder de una buena siesta - Muad'Dib
Intenté recrear esto. Si especifiqué "ItemDetails" en la vista base, mostraría la plantilla ItemDetails en lugar de la plantilla "Item" correctamente. Si especifiqué "ItemDetails" dentro de la plantilla "Item", no sucedió nada, como mencionaste. No sé si esto es un error, pero fue un comportamiento inesperado. - DMulligan
Necesitamos la definición de Item y ItemsList - Erik Funkenbusch