Una delle cose maggiormente apprezzabili del modello di sviluppo MVC (se non sapete cos'è, leggete qui) è l'importanza data all'organizzazione del codice: la separazione logica dei tre aspetti di cui si compone l'applicazione si concretizza all'interno delle directory del progetto: in particolare, visto che il Model è spesso delegato a librerie esterne e relativi abstraction layers, alle cartelle /Controllers/ e /Views/, che ospitano rispettivamente gli input handler e la user interface dell'applicazione.
Tra queste, la cartella /Views/ riveste una particolare importanza a livello di filesystem in quanto viene utilizzata dal View Engine per reperire automaticamente le viste richiamate dai nostri Controller. Questa ricerca viene effettuata attraverso un insieme di percorsi di ricerca predefiniti che costituiscono il cosiddetto default location scheme. Si tratta in buona sostanza di un elenco di pattern di ricerca relativi a percorsi locali. Quella che segue è la parte del default location scheme del Razor View Engine relativa alle normali View:
1 2 3 4 5 6 7 |
ViewLocationFormats = new string[] { "~/Views/{1}/{0}.cshtml", "~/Views/{1}/{0}.vbhtml", "~/Views/Shared/{0}.cshtml", "~/Views/Shared/{0}.vbhtml" }; |
Se volete dare un'occhiata al location scheme completo, che include anche i default pattern per le Partial Views, Area Views, Master Views et. al., potete farlo tramite questa pagina.
Tornando alla porzione riportata in alto, è possibile notare due placeholder, {0} e {1}, che si riferiscono rispettivamente al nome della Action e del relativo Controller. Il funzionamento è del tutto evidente: il View Engine controlla la presenza di una vista compatibile nei percorsi più comuni, dando la priorità ai path più specifici e quindi cercando in quello convenzionalmente dedicato alle viste condivise.
La domanda, a questo punto, nasce spontanea: come possiamo fare ad aggiungere altre convenzioni? O meglio, come possiamo modificare quella lista, magari aggiungendo una o più cartelle compatibili con la logica che abbiamo deciso di adottare per creare il nostro albero di cartelle in cui organizzare le View? E' infatti evidente che, se non troviamo il modo di farlo, qualsiasi tentativo di organizzare le nostre View in modo non conforme a quanto previsto da ASP.NET si tradurrà nel seguente messaggio di errore:
The view 'YourView' or its master was not found or no view engine supports the searched locations. The following locations were searched:
Le risposte più comuni che si trovano in rete propongono soluzioni piuttosto complesse da implementare, come creare un nuovo View Engine estendendo il RazorViewEngine o il WebFormViewEngine, riscrivere la collection ViewEngines.Engines e altri approcci non esattamente developer-friendly.
Fortunatamente, esiste un metodo estremamente semplice che consente di modificare il location scheme predefinito con pochissime righe di codice e senza creare o estendere nessuna classe: è sufficiente aggiungere le seguenti righe al metodo Application_Start del Global.asax:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
protected void Application_Start() { // ---------------------------------------------- // *** EXISTING CODE HERE - DO NOT DELETE IT! *** // ---------------------------------------------- // ... // Add /MyVeryOwn/ folder to the default location scheme for STANDARD Views var razorEngine = ViewEngines.Engines.OfType<RazorViewEngine>().FirstOrDefault(); razorEngine.ViewLocationFormats = razorEngine.ViewLocationFormats.Concat(new string[] { "~/MyVeryOwn/{1}/{0}.cshtml", "~/MyVeryOwn/{0}.cshtml" // add other folders here (if any) }).ToArray(); // Add /MyVeryOwnPartialFolder/ folder to the default location scheme for PARTIAL Views razorEngine.PartialViewLocationFormats = razorEngine.PartialViewLocationFormats.Concat(new string[] { "~/MyVeryOwnPartialFolder/{0}.cshtml" // add other folders here (if any) }).ToArray(); } |
L'esempio sopra indicato aggiunge una cartella (con o senza Controller) ai percorsi di ricerca predefiniti previsti per le View e per le Partial View con un impatto estremamente contenuto sul nostro progetto. E' ovviamente possibile aggiungere un qualsiasi numero di cartelle a questi due array e/o a qualsiasi altro gruppo relativo alle varie tipologie di View. Per un elenco completo, potete fare riferimento alla pagina già menzionata poco fa.
Per il momento è tutto: felice sviluppo!