¿Cómo especifico diferentes diseños en el archivo ViewStart de la maquinilla de afeitar ASP.NET MVC 3?

313

Me gustaría tener 2 diseños separados en mi aplicación. Digamos que uno es para la sección Pública del sitio web y el otro es para el miembro.

Por simplicidad, digamos que toda la lógica de cada uno de estos sitios está perfectamente integrada en 2 controladores distintos.

  • PublicController
  • StaffController

Y que cada uno tiene un diseño correspondiente para toda la vista debajo de cada uno.

  • _PublicLayout.cshtml
  • _StaffLayout.cshtml

¿Cómo uso el archivo _ViewStart.cshtml para especificar que todas las vistas / acciones en "Público" usan PublicLayout y todo en "Personal" usa StaffLayout?

¡Gracias!

Justin
fuente
44
Por si acaso: si desea eliminar el diseño de una Razorvista determinada , simplemente configureLayout = null;
Leniel Maccaferri
3
Como comentario a su ejemplo, probablemente no debería tener controladores llamados Público y Personal. Los controladores se implementan con mayor frecuencia como el punto de entrada a una acción similar a CRUD en ciertas entidades comerciales clave, como EventController, UserController o similares. Si su solicitud es razonablemente grande, la responsabilidad de un controlador Público / Personal sería demasiado amplia. Considere las áreas en su lugar. msdn.microsoft.com/en-us/library/ee671793%28VS.100%29.aspx Puede ser consciente de esto, pero alguien que lea esto podría tener una idea equivocada, así que solo para el registro.
Alex

Respuestas:

558

Podría poner un _ViewStart.cshtmlarchivo dentro de la /Views/Publiccarpeta que anularía el predeterminado en la /Viewscarpeta y especificar el diseño deseado:

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

Por analogía, podría poner otro _ViewStart.cshtmlarchivo dentro de la /Views/Staffcarpeta con:

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

También puede especificar qué diseño se debe usar al devolver una vista dentro de una acción del controlador, pero eso es por acción:

return View("Index", "~/Views/Shared/_StaffLayout.cshtml", someViewModel);

Otra posibilidad es un filtro de acción personalizado que anularía el diseño. Como puede ver muchas posibilidades para lograr esto. Depende de usted elegir cuál se adapta mejor a su situación.


ACTUALIZAR:

Como se solicitó en la sección de comentarios, aquí hay un ejemplo de un filtro de acción que elegiría una página maestra:

public class LayoutInjecterAttribute : ActionFilterAttribute
{
    private readonly string _masterName;
    public LayoutInjecterAttribute(string masterName)
    {
        _masterName = masterName;
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);
        var result = filterContext.Result as ViewResult;
        if (result != null)
        {
            result.MasterName = _masterName;
        }
    }
}

y luego decorar un controlador o una acción con este atributo personalizado que especifica el diseño que desea:

[LayoutInjecter("_PublicLayout")]
public ActionResult Index()
{
    return View();
}
Darin Dimitrov
fuente
1
@DarinDimitrov Donde crearé LayoutInjecterAttribute. ? ¿Hay alguna ubicación en particular?
kbvishnu
2
@VeeKeyBee, puedes ponerlo dentro de una ActionFilterssubcarpeta.
Darin Dimitrov
Un problema potencial con LayoutInjecterAttribute: Se llama antes del OnExceptionmétodo del controlador . Entonces, si el controlador proporciona un resultado de vista durante el manejo de excepciones, el diseño no se establecerá.
Jeff Sharp
Como nuevo chico de MVC, me gustaría dar las gracias por enseñarme mucho en esta respuesta. Sin embargo, no entiendo lo que está sucediendo dentro OnActionExecuted. ¿Puedes actualizar la respuesta por mí?
Imad
29

Un método más es definir el diseño dentro de la vista:

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

Puede encontrar más formas de hacerlo aquí , espero que esto ayude a alguien.

shaijut
fuente
1
Esto no funcionará: sin el _ViewStart.cshtml separado, su vista aún se representará dentro del método @RenderBody () en el otro diseño.
Tillman32
¡Esta! ¿Por qué todos presentan estos procesos extremadamente complejos cuando todo lo que necesitas hacer es esto?
George Harnwell
15

Este método es la forma más sencilla para que los principiantes controlen el renderizado de Layouts en su aplicación ASP.NET MVC. Podemos identificar el controlador y representar los diseños como controlador par, para hacer esto podemos escribir nuestro código en el archivo _ViewStart en el directorio raíz de la carpeta Vistas. El siguiente es un ejemplo que muestra cómo se puede hacer.

@{
    var controller = HttpContext.Current.Request.RequestContext.RouteData.Values["Controller"].ToString();
    string cLayout = "";

    if (controller == "Webmaster")
        cLayout = "~/Views/Shared/_WebmasterLayout.cshtml";
    else
        cLayout = "~/Views/Shared/_Layout.cshtml";

    Layout = cLayout;
}

Lea el artículo completo aquí "Cómo renderizar diferentes diseños en ASP.NET MVC"

Anil Sharma
fuente