¿Dónde y cómo se vincula el archivo de diseño _ViewStart.cshtml?

199

Aquí está el About.cshtml de la plantilla MVC 3 predeterminada:

@{
    ViewBag.Title = "About Us";
}

<h2>About</h2>
<p>
     Put content here.
</p>

Esperaría que se encontrara una referencia al archivo _ViewStart en el About.cshtml, pero claramente no lo es.

He buscado global.asaxy web.config, pero no puedo descubrir cómo About.cshtmlse "vincula" el archivo con el diseño del archivo _ViewStart.

Todo funciona como se esperaba, me gustaría saber qué está pasando bajo el capó ...

Kman
fuente

Respuestas:

237

Del blog de ScottGu :

Comenzando con la versión Beta de ASP.NET MVC 3, ahora puede agregar un archivo llamado _ViewStart.cshtml (o _ViewStart.vbhtml para VB) debajo de la carpeta \ Views de su proyecto:

El archivo _ViewStart se puede usar para definir el código de vista común que desea ejecutar al comienzo de la representación de cada vista. Por ejemplo, podríamos escribir código dentro de nuestro archivo _ViewStart.cshtml para establecer mediante programación la propiedad de Diseño para cada Vista para que sea el archivo SiteLayout.cshtml de forma predeterminada:

Debido a que este código se ejecuta al comienzo de cada Vista, ya no necesitamos establecer explícitamente el Diseño en ninguno de nuestros archivos de vista individuales (excepto si deseamos anular el valor predeterminado anterior).

Importante: Debido a que _ViewStart.cshtml nos permite escribir código, opcionalmente podemos hacer que nuestra lógica de selección de diseño sea más rica que solo un conjunto de propiedades básicas. Por ejemplo: podríamos variar la plantilla de diseño que usamos según el tipo de dispositivo que accede al sitio, y tener un diseño optimizado para teléfono o tableta para esos dispositivos, y un diseño optimizado para computadoras de escritorio / computadoras portátiles. O si estuviéramos creando un sistema CMS o una aplicación compartida común que se usa en varios clientes, podríamos seleccionar diferentes diseños para usar según el cliente (o su función) al acceder al sitio.

Esto permite mucha flexibilidad de interfaz de usuario. También le permite escribir más fácilmente la lógica de vista una vez, y evitar repetirla en múltiples lugares.

También mira esto .

jim tollan
fuente
14
Entonces, ¿es más o menos una característica "codificada" de MVC3? No necesito cambiarlo a otra página "predeterminada", solo tengo curiosidad por saber cómo se configuró. Gracias por resolverlo todo :)
Kman
2
Kman- Hardcoded, por convención (elija otro 'identificador' aquí :)), así que sí, exactamente. me alegro de que despejó la niebla
jim tollan
No es solo en su carpeta "Vistas" donde podría necesitarlo. Si agrega un RazorViewEngine personalizado para organizar las vistas en otras carpetas, también debe incluir el archivo en la raíz de esas carpetas de vista alternativas. Por ejemplo, moví todas las vistas de plantilla de Inspinia a una carpeta y ejecuté esto en el motor de vista ViewLocationFormats = ViewLocationFormats.Union(new string[] { "~/Inspinia/ExampleViews/{1}/{0}.cshtml" }).ToArray();. Como resultado, tuve que agregar una copia de mi archivo _ViewStart.cshtml a "~ / Inspinia / ExampleViews", de lo contrario no se recogió y no se configuró ningún diseño.
Triynko
2
Si su carpeta Vistas tiene subcarpetas, ¿puede poner una _ViewStarten cada subcarpeta que se vincule a las vistas en esa subcarpeta?
toddmo
35

En un sentido más general, esta capacidad del marco MVC para "saber" sobre _Viewstart.cshtml se llama "Codificación por convención".

La convención sobre la configuración (también conocida como codificación por convención) es un paradigma de diseño de software que busca disminuir la cantidad de decisiones que los desarrolladores deben tomar, ganando simplicidad, pero no necesariamente perdiendo flexibilidad. La frase esencialmente significa que un desarrollador solo necesita especificar aspectos no convencionales de la aplicación. Por ejemplo, si hay una clase Venta en el modelo, la tabla correspondiente en la base de datos se llama "ventas" de forma predeterminada. Solo si uno se desvía de esta convención, como llamar a la tabla "productos_vendidos", es necesario escribir código con respecto a estos nombres.

Wikipedia

No hay magia en eso. Se acaba de escribir en la base de código central del marco MVC y, por lo tanto, es algo que MVC "sabe". Por eso no lo encuentras en los archivos .config ni en ningún otro lugar; en realidad está en el código MVC. Sin embargo, puede anular para alterar o anular estas convenciones.

rismo
fuente
13
Si MVC lo sabe, ¿por qué Visual Studio no lo sabe y me lo señala? Si codificar por convención significa que las cosas funcionan siempre y cuando no rompas la convención, apesta ...
Arne Evertsson
No romper la convención es una especie de punto. AKAIK Ruby on Rails también sigue este paradigma.
Umar Farooq Khawaja
+1 Raif. No tiene sentido defender la "codificación por convención" mal documentada. Podría decir eso sobre cualquiera de mis códigos anteriores. "¿Qué? ¿No esperabas que se bloqueara cuando llegó a 33? Todo el mundo sabe que omites 33". Desafortunadamente, la brecha de documentación para ASP.NET MVC es enorme. Los únicos documentos de MS se generan automáticamente sin resúmenes de origen internos.
Shannon
66
La convención sobre la configuración no significa que no pueda cambiarla. DEBERÍA haber una configuración disponible para poder especificar el nombre y la ubicación de ese archivo. Puede muy bien haberlo, pero quién sabe qué es. La gente usa el mantra "convención sobre configuración" para cubrir una multitud de malas decisiones en una base de código y me molestó un poco como el tipo que aparece después del hecho para mantener su desorden mal documentado que "simplemente funciona" (pero Dios no permita que cambies nada, pasarás horas descubriendo cómo rompiste todo).
Robert C. Barth
3
@AidenStrydom No estoy de acuerdo. La respuesta aceptada en realidad me dice cómo usar _ViewStart. Esta respuesta solo habla de un concepto de diseño. Vine aquí para obtener información sobre _ViewStart, no información sobre por qué Visual Studio no me dijo nada sobre _ViewStart.
Millie Smith
23

Solo otro pensamiento.

Si desea tener su propio cshtmlarchivo como plantilla común, puede hacerlo de esta manera

Dentro de tu _viewstart.cshtmlpuedes mencionar tu cshtmlarchivo común .

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

El código fuente es un lugar mucho mejor para buscar esto que la documentación.

Haciendo referencia al código MVC 6 de Github, tenemos algunos archivos de interés.

----actualizar----

Debido a los cambios en la estructura de origen, la información sobre cómo se recopilan las páginas viewstart ahora se puede encontrar en RazorViewEngine.cs. Busque la función "GetViewStartPages".

----/actualizar----

Para responder cómo entran en juego, mira RazorView , que creo (debido a IView) está vinculado a la tubería de MVC. Este archivo tiene un método RenderAsync que se llama desde la canalización de MVC para representar la vista solicitada.

RenderAsync realiza llamadas a RenderPage Y LUEGO RenderLayout (TENGA EN CUENTA EL PEDIDO). El RenderPage primero realiza llamadas para tratar con archivos viewstart (nota plural, podría haber más de un archivo _viewstart).

Por lo tanto, la información que busca se puede obtener de la función RenderViewStartAsync en el archivo RazorView.cs en el espacio de nombres Microsoft.AspNet.Mvc.Razor.

Frison Alexander
fuente
7

Esto puede agregar información adicional a esta pregunta ahora (2016 ala MVC4, MVC5).

El motor Razor encuentra y ejecuta el código en _ViewStart.cshtml antes que cualquier otro código que esté en el mismo directorio o subdirectorio donde se encuentra _ViewStart.cshtml .

Cualquier vista puede anular la propiedad Diseño o cualquiera de sus valores.

Solo pensé que podría agregar un poco más de información para mostrarle por qué es _ViewStart.

Si obtiene ILSpy y examina el código en RazorViewEngine (System.Web.Mvc.dll) verá que el código hace referencia a ese nombre.

_ViewStart en System.Web.Mvc.dll

Puede ver que RazorViewEngine busca un archivo con ese nombre:

código de razorviewengine

RazorViewEngine.ViewStartFileName = "_ViewStart";
raddevus
fuente
3
esto es lo que estaba buscando, odio "no sé" lo que está sucediendo en mi proyecto, porque también estoy haciendo mis propias plantillas para VS y este archivo que acaba de salir del aire fue muy desagradable de entender
Sebastian 506563
1

Si desea tener un diseño común para sus páginas, necesita definir el diseño común y asociar una vista con el diseño, tenemos que establecer la propiedad del diseño en todas y cada una de las vistas, esto viola el principio DRY (No repetir). Para esto, .Net Framework ha proporcionado el archivo "_ViewStart.cshtml", ubicado dentro de la carpeta de vista. Colocamos la información de diseño en el archivo "_ViewStart.cshtml" y cada vista utiliza de manera predeterminada esta información de diseño. Si desea proporcionar información de diseño diferente, supongamos que en su vista de Inicio, puede crear un nuevo "_ViewStart.cshtml" con referencia a ese diseño y colocarlo en la carpeta "Vista de Inicio".

KamalDeep
fuente
1

La respuesta corta es : ViewStarts comienza primero cuando se visualiza cualquier vista. La larga historia está a continuación:

La historia de la creación de un archivo de vista única:

  1. ViewStart se fusiona con ViewImports y luego se ejecuta como un solo archivo. Tenga en cuenta que ViewImports siempre se combina con cualquier archivo cshtml, incluido el archivo ViewStart. Su propósito es abstraer las declaraciones @using y otras directivas comunes.
  2. La salida de ViewStart (como Layout y ViewData) está disponible para el archivo View específico.
  3. Dentro del archivo Ver, si la variable Diseño es / se vuelve nula, el cuerpo de la vista se representa y el resultado final se entrega al usuario.
  4. Si la variable de diseño es / no es nula, la ejecución se mueve al archivo de diseño que a su vez se fusiona con ViewImports como un solo archivo y luego, en la instrucción @RenderBody () dentro de la ejecución del archivo de diseño, se mueve de nuevo al archivo de vista que se fusiona con ViewImports nuevamente y la salida se fusiona con el archivo de diseño en la ubicación de @RenderBody () y la salida final finalmente se entrega al usuario.

Espera que esto te haga consciente de lo que realmente está sucediendo dentro de los misterios desconocidos del ciclo de vida de tu programa.

Shadi Namrouti
fuente