Obligar a todas las áreas a utilizar el mismo diseño

88

Tengo la siguiente estructura de proyecto:

  • / Vistas / Compartido / _Layout;

  • / Areas / Area1 / Views / ControllerName / Index;

...

  • / Areas / AreaN / Views / ControllerName / Index.

¿Hay alguna forma de obligar a todas las áreas a utilizar _Layout como diseño base ?

¿Hay alguna forma de hacerlo sin agregar el archivo _ViewStart (por ejemplo, a través de la configuración de enrutamiento)?

Ver también:

¿Cómo especifico diferentes diseños en el archivo ASP.NET MVC 3 razor ViewStart?

Mikhail
fuente
Aquí hay una buena respuesta y otra
Rafael Emshoff

Respuestas:

155

Solo tienes que agregar un archivo llamado:

_ViewStart.cshtml

Debajo de cada carpeta de vistas de área:

/Areas/Area1/Views/_ViewStart.cshtml

Y edite el archivo para que apunte al diseño raíz de esta manera:

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

Para que esto funcione, no tiene que especificar un valor en la propiedad de diseño de la vista, si lo hace, estaría anulando el diseño global

Nota: Como mencionó Tony, puede editar la propiedad de diseño de cada vista para que apunte al diseño raíz, sin embargo, esta no es la forma recomendada de hacerlo, ya que acoplaría sus vistas con su diseño y cambiarlo sería doloroso.

Editar 1

Si desea utilizar código para establecer el diseño de la vista predeterminada, tal vez debería considerar escribir un motor de vista personalizado.

Intente buscar en Google sobre personalizado RazorViewEngineyRazorView

Este artículo podría ser un buen punto de partida.

http://weblogs.asp.net/imranbaloch/archive/2011/06/27/view-engine-with-dynamic-view-location.aspx

No he hecho algo como esto pero espero estar apuntando en la dirección correcta

Jupaol
fuente
1
¿Hay alguna forma de hacerlo sin agregar el archivo "_ViewStart" (por ejemplo, a través de la configuración de enrutamiento)?
Mikhail
2
Dentro del enrutamiento no lo creo. Son dos cosas diferentes. El enrutamiento se encarga de tratar de hacer coincidir la URL de solicitud actual con una ruta registrada en la RoutesTable, cuando se encuentra una coincidencia, se crea un IMvcRouteHandler y luego un IHttpHandler (MvcHandler) se encarga de procesar la acción de su controlador. Como puede ver, esto no tiene nada que ver con vistas ni diseños. Esto se debe a que una ruta no necesariamente devuelve una vista, podría devolver json o xml. Entonces, el enrutamiento no es el lugar correcto para implementar algo como esto.
Jupaol
También puede agregar el _ViewStartdirectamente en la carpeta Área directamente para aplicarlo a todas las áreas.
Artur
21

Ampliando la respuesta de Jupaol ...

Al menos en VS2013, el archivo _ViewStart.cshtml se agrega de forma predeterminada al crear el área, por lo que ya está allí, y puede cambiar el contenido como señala para apuntar a la raíz _Layout.cshtml. Luego puede eliminar el _Layout.cshtml en el área, ya que ya no se usa (y ahora es una fuente potencial de confusión)

Sin embargo, al hacerlo, cualquier enrutamiento realizado en esa raíz _Layout.cshtml deberá considerar áreas.
El _Layout.cshtml predeterminado tiene varios ayudantes de ActionLink que necesitan una ligera modificación:

Agregue el parámetro RouteValueDictionary a cualquier llamada de ActionLink estableciendo Area = "". Tenga en cuenta que la cadena vacía se refiere al nivel raíz. Esto permitirá que estos enlaces funcionen correctamente cuando se invoquen desde dentro de un área y seguirán funcionando cuando se invoquen desde la raíz.

p.ej:

<li>@Html.ActionLink("Home", "Index", "Home", new { Area = "" }, null)</li>
Rob Campbell
fuente
2

Usted especifica un diseño usando:

@ {Layout = "_Layout"; }

Si desea que esto sea más fácil, cambie todos a la vez. Quizás podría simplemente configurarlo como una variable de bolsa de vista y pasarlo al controlador. Para hacerlo aún más fácil, puede crear un controlador base del que hereden los otros controladores y hacer que asigne el diseño a la bolsa de vista allí.

No estoy seguro de por qué debería cambiar el enrutamiento o tal vez no lo entiendo. Espero que esto ayude :)

Tony
fuente