¿Por qué RazorViewEngine no detecta mi DisplayTemplate?

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.

preguntado el 03 de mayo de 12 a las 21:05

Es probable que no sea un error. Escriba un título más útil/relevante. -

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

nunca subestimes el poder de una buena siesta -

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

Necesitamos la definición de Item y ItemsList -

3 Respuestas

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

intenta usar @Html.RenderPartial("ItemDetails", item)

contestado el 03 de mayo de 12 a las 22:05

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 or haz tu propia pregunta.