Pregunta Razor anidado diseños con secciones en cascada


Tengo un sitio MVC3 usando Razor como su motor de visualización. Quiero que mi sitio sea skinnable La mayoría de las máscaras posibles son lo suficientemente similares como para que puedan derivarse de un diseño maestro compartido.

Por lo tanto, estoy considerando este diseño:

Planned view diagram

Sin embargo, me gustaría poder llamar RenderSection en la capa inferior, _Common.cshtmly hacer que represente una sección definida en la capa superior Detail.cshtml. Esto no funciona: RenderSection aparentemente solo representa las secciones que se definen la siguiente capa.

Por supuesto, puedo definir cada sección en cada skin. Por ejemplo, si _Common necesita llamar RenderSection("hd") para una sección definida en Detail, Simplemente coloco esto en cada _Skin y funciona:

@section hd {
    @RenderSection("hd")
}

Esto da como resultado una cierta duplicación de código (ya que cada máscara debe tener ahora esta misma sección) y generalmente se siente desordenada. Todavía soy nuevo en Razor, y parece que me podría estar perdiendo algo obvio.

Cuando se depura, puedo ver la lista completa de secciones definidas en WebViewPage.SectionWritersStack. Si pudiera decirle a RenderSection que revisara toda la lista antes de renunciar, encontraría la sección que necesito. Por desgracia, SectionWritersStack no es público.

Alternativamente, si pudiera acceder a la jerarquía de páginas de diseño e intentar la ejecución de RenderSection en cada contexto diferente, podría ubicar la sección que necesito. Probablemente me esté perdiendo algo, pero no veo ninguna forma de hacer esto.

¿Hay alguna forma de lograr este objetivo, que no sea el método que ya he descrito?


76
2018-04-02 20:16


origen


Respuestas:


Esto de hecho no es posible hoy usando la API pública (que no sea el uso del enfoque de redefinición de sección). Puede tener algo de suerte utilizando la reflexión privada, pero eso por supuesto es un enfoque frágil. Veremos cómo hacer que este escenario sea más fácil en la próxima versión de Razor.

Mientras tanto, aquí hay un par de publicaciones de blog que he escrito sobre el tema:


35
2018-04-03 04:48



@helper ForwardSection( string section )
{
   if (IsSectionDefined(section))
   {
       DefineSection(section, () => Write(RenderSection(section)));
   }
}

¿Esto haría el trabajo?


16
2017-10-15 21:37



No estoy seguro si esto es posible en MVC 3 pero en MVC 5 puedo hacerlo con éxito usando el siguiente truco:

En ~/Views/Shared/_Common.cshtml escribe tu código HTML común como:

<!DOCTYPE html>
<html lang="fa">
<head>
    <title>Skinnable - @ViewBag.Title</title>
</head>
<body>
@RenderBody()
</body>
</html>

En ~/Views/_ViewStart.cshtml:

@{
    Layout = "~/Views/Shared/_Common.cshtml";
}

Ahora todo lo que tienes que hacer es usar el _Common.cshtml como el Layout para todas las pieles. Por ejemplo, en ~/Views/Shared/Skin1.cshtml:

@{
    Layout = "~/Views/Shared/_Common.cshtml";
}

<p>Something specific to Skin1</p>

@RenderBody()

Ahora puede establecer la máscara como su diseño en el controlador o en la vista según sus criterios. Por ejemplo:

    public ActionResult Index()
    {
        //....
        if (user.SelectedSkin == Skins.Skin1)
            return View("ViewName", "Skin1", model);
    }

Si ejecuta el código anterior, debe obtener una página HTML con el contenido de Skin1.cshtml y _Common.cshtml

En resumen, configurará el diseño de la página de diseño (máscara).


4
2017-12-29 15:13



No estoy seguro si esto lo ayudará, pero escribí algunos métodos de extensión para ayudar a las secciones "burbujear" dentro de los parciales, que también deberían funcionar para diseños anidados.

Inyectar contenido en secciones específicas de una vista parcial ASP.NET MVC 3 con Razor View Engine

Declarar en diseño / vista / parcial del niño

@using (Html.Delayed()) {
    <b>show me multiple times, @Model.Whatever</b>
}

Renderizar en cualquier padre

@Html.RenderDelayed();

Consulte el enlace de respuesta para ver más casos de uso, como solo representar un bloque retrasado incluso si se declara en una vista repetitiva, mostrar bloques retrasados ​​específicos, etc.


1
2017-12-09 20:46