Dove e come è collegato il file di layout _ViewStart.cshtml?


199

Ecco About.cshtml dal modello MVC 3 predefinito:

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

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

Mi aspetto che un riferimento al file _ViewStart venga trovato nel file About.cshtml, ma chiaramente non lo è.

Ho cercato global.asaxe web.config, ma non riesco a scoprire come il About.cshtmlfile è "collegato" al layout dal file _ViewStart.

Tutto funziona come previsto, vorrei solo sapere cosa sta succedendo sotto il cofano ...

Risposte:


237

Dal blog di ScottGu :

A partire dalla versione beta di ASP.NET MVC 3, ora puoi aggiungere un file chiamato _ViewStart.cshtml (o _ViewStart.vbhtml per VB) sotto la cartella \ Views del tuo progetto:

Il file _ViewStart può essere utilizzato per definire il codice della vista comune che si desidera eseguire all'inizio del rendering di ciascuna vista. Ad esempio, potremmo scrivere il codice nel nostro file _ViewStart.cshtml per impostare a livello di codice la proprietà Layout per ogni vista in modo che sia il file SiteLayout.cshtml per impostazione predefinita:

Poiché questo codice viene eseguito all'inizio di ciascuna vista, non è più necessario impostare esplicitamente il layout in nessuno dei nostri singoli file di vista (tranne se volessimo sovrascrivere il valore predefinito sopra).

Importante: poiché _ViewStart.cshtml ci consente di scrivere codice, possiamo facoltativamente rendere la nostra logica di selezione del layout più ricca di un semplice set di proprietà. Ad esempio: potremmo variare il modello di layout che utilizziamo in base al tipo di dispositivo che accede al sito e disporre di un layout ottimizzato per telefono o tablet per tali dispositivi e un layout ottimizzato per desktop per PC / laptop. O se stessimo costruendo un sistema CMS o un'app condivisa comune che viene utilizzata su più clienti, potremmo selezionare diversi layout da utilizzare a seconda del cliente (o del loro ruolo) quando si accede al sito.

Ciò consente molta flessibilità dell'interfaccia utente. Inoltre, consente di scrivere più facilmente la logica di visualizzazione una volta ed evitare di ripeterla in più punti.

Vedi anche questo .


14
Quindi è più o meno una funzionalità "hardcoded" di MVC3? Non ho bisogno di cambiarlo in un'altra pagina "predefinita", solo curioso di come è stato impostato. Grazie per aver risolto tutto :)
Kman,

2
Kman - Hardcoded, per convenzione (scegli un altro "handle" qui :)) - quindi sì, esattamente. felice di aver ripulito la nebbia
Jim Tollan,

Non è solo nella cartella "Visualizzazioni" che potresti averne bisogno. Se si aggiunge un RazorViewEngine personalizzato per organizzare le viste in altre cartelle, è necessario includere anche il file nella radice di quelle cartelle di viste alternative. Ad esempio, ho spostato tutte le viste del modello Inspinia in una cartella e l'ho eseguito nel motore di visualizzazione ViewLocationFormats = ViewLocationFormats.Union(new string[] { "~/Inspinia/ExampleViews/{1}/{0}.cshtml" }).ToArray();. Di conseguenza, ho dovuto aggiungere una copia del mio file _ViewStart.cshtml a "~ / Inspinia / ExampleViews", altrimenti non è stato prelevato e non è stato impostato alcun layout.
Triynko,

2
Se la cartella Viste contiene sottocartelle, puoi inserire una _ViewStartsottocartella che si collegherà alle viste in quella sottocartella?
toddmo,

35

In senso più generale, questa capacità del framework MVC di "conoscere" _Viewstart.cshtml è chiamata "Coding by convention".

La convenzione sulla configurazione (nota anche come codifica per convenzione) è un paradigma di progettazione software che cerca di ridurre il numero di decisioni che gli sviluppatori devono prendere, acquisendo semplicità, ma non necessariamente perdendo flessibilità. La frase essenzialmente significa che uno sviluppatore deve solo specificare aspetti non convenzionali dell'applicazione. Ad esempio, se nel modello è presente una classe Vendita, la tabella corrispondente nel database è denominata "vendite" per impostazione predefinita. È solo se si discosta da questa convenzione, come chiamare la tabella "prodotti_venduti", è necessario scrivere il codice relativo a questi nomi.

Wikipedia

Non c'è magia ad esso. È appena stato scritto nel codice base del framework MVC ed è quindi qualcosa che MVC "conosce". Ecco perché non lo trovi nei file .config o altrove; è in realtà nel codice MVC. È comunque possibile eseguire l'override per modificare o annullare queste convenzioni.


13
Se MVC lo sa, allora perché Visual Studio non lo sa e me lo fa notare? Se codificare per convenzione significa che le cose funzionano fintanto che ti capita di non infrangere la convenzione che fa schifo ...
Arne Evertsson,

Non infrangere la convenzione è un po 'il punto. Anche AKAIK Ruby on Rails segue questo paradigma.
Umar Farooq Khawaja,

+1 Raif. Inutile difendere la "codifica per convenzione" scarsamente documentata. Potrei dire questo su qualsiasi mio codice all'indietro. "Cosa? Non ti aspettavi che andasse in crash quando è arrivato a 33? Tutti sanno che salti 33." Sfortunatamente, il divario nella documentazione per ASP.NET MVC è enorme. Gli unici documenti MS vengono generati automaticamente senza riepiloghi di origine interni.
Shannon,

6
La convenzione sulla configurazione non significa che non puoi cambiarla. DOVREBBE essere disponibile la configurazione per poter specificare il nome e il percorso di quel file. Potrebbe anche esserci, ma chissà di cosa si tratta. La gente usa il mantra della "convenzione sulla configurazione" per coprire una moltitudine di decisioni sbagliate in una base di codice e mi fa incazzare come il tipo che viene dopo il fatto di mantenere il loro disordine mal documentato che "funziona" (ma Dio non ti permetta di cambiare nulla - passerai ore a capire come hai rotto tutto).
Robert C. Barth,

3
@AidenStrydom Non sono d'accordo. La risposta accettata in realtà mi dice come usare _ViewStart. Questa risposta parla solo di un concetto di design. Sono venuto qui per informazioni su _ViewStart, non informazioni sul motivo per cui Visual Studio non mi avrebbe detto nulla su _ViewStart.
Millie Smith,

23

Solo un altro pensiero.

Se vuoi avere il tuo cshtmlfile come modello comune, puoi farlo in questo modo

All'interno del tuo _viewstart.cshtmlpuoi citare il tuo cshtmlfile comune .

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

14

Il codice sorgente è un posto molto migliore per cercarlo rispetto alla documentazione.

Facendo riferimento al codice MVC 6 di Github, abbiamo alcuni file di interesse

----aggiornare----

A causa di modifiche alla struttura di origine, le informazioni su come vengono raccolte le pagine viewstart ora possono essere trovate in RazorViewEngine.cs cercare la funzione "GetViewStartPages".

----/aggiornare----

Per rispondere a come entrano in gioco, guarda RazorView , che credo (a causa di IView) sia collegato alla pipeline MVC. Questo file ha un metodo RenderAsync che viene chiamato dalla pipeline MVC per eseguire il rendering della vista richiesta.

RenderAsync effettua chiamate a RenderPage E POI a RenderLayout (NOTA L'ORDINE). RenderPage prima effettua chiamate per gestire i file viewstart (nota al plurale, potrebbe esserci più di un file _viewstart).

Pertanto, le informazioni ricercate possono essere ottenute dalla funzione RenderViewStartAsync nel file RazorView.cs nello spazio dei nomi Microsoft.AspNet.Mvc.Razor.


7

Questo potrebbe aggiungere alcune informazioni aggiuntive a questa domanda ora (2016 ala MVC4, MVC5).

Il motore Razor trova ed esegue il codice in _ViewStart.cshtml prima di qualsiasi altro codice che si trova nella stessa directory o sottodirectory in cui si trova _ViewStart.cshtml .

Qualsiasi vista può sovrascrivere la proprietà Layout o uno qualsiasi dei suoi valori.

Ho pensato di aggiungere qualche informazione in più per mostrarti perché è _ViewStart.

Se ottieni ILSpy ed esamini il codice in RazorViewEngine (System.Web.Mvc.dll) vedrai che il codice stesso fa riferimento a quel nome.

_ViewStart in System.Web.Mvc.dll

Puoi vedere che RazorViewEngine cerca un file con quel nome:

codice razorviewengine

RazorViewEngine.ViewStartFileName = "_ViewStart";

3
questo è quello che stavo cercando, odio "non so" cosa sta succedendo nel mio progetto, perché sto anche facendo i miei modelli per VS e questo file che è appena uscito dall'aria era molto sfortunato da capire
Sebastian 506563

1

Se vuoi avere un layout comune per le tue pagine devi definire il layout comune e per associare una vista al layout dobbiamo impostare la proprietà del layout su ogni vista, questo viola il principio DRY (Don't Repeat Yourself). Per questo .Net Framework ha fornito il file "_ViewStart.cshtml", collocato nella cartella della vista. Inseriamo le informazioni di layout nel file "_ViewStart.cshtml" e ogni vista di default utilizza queste informazioni di layout. Se si desidera fornire alcune informazioni di layout diverse, supponiamo che la vista Home sia possibile, è possibile creare un nuovo "_ViewStart.cshtml" con riferimento a quel layout e posizionarlo nella cartella "Vista Home".


1

La risposta breve è : ViewStarts inizia per primo quando viene visualizzata una vista. La lunga storia è sotto:

La storia della creazione di un file a vista singola:

  1. ViewStart viene unito a ViewImports e quindi eseguito come un singolo file. Si noti che ViewImports è sempre unito a qualsiasi file cshtml incluso il file ViewStart. Il suo scopo è quello di astrarre dichiarazioni @using e altre direttive comuni.
  2. L'output di ViewStart (come Layout e ViewData) diventa disponibile per il file View specifico.
  3. All'interno del file Visualizza, se la variabile Layout è / diventa nulla, il corpo della vista viene reso e l'output finale viene consegnato all'utente.
  4. Se la variabile di layout è / non diventa nulla, l'esecuzione viene spostata nel file di layout che a sua volta viene unito a ViewImports come un singolo file e quindi nell'istruzione @RenderBody () all'interno dell'esecuzione del file di layout viene riportato nel file di visualizzazione che si unisce nuovamente a ViewImports e l'output viene unito al file di layout nella posizione di @RenderBody () e l'output finale viene infine consegnato all'utente.

Spero che questo ti renda consapevole di ciò che sta realmente accadendo all'interno dei misteri sconosciuti del ciclo di vita del tuo programma.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.