Come specificare la posizione in cui verrà creata una vista Mvc per un controller Mvc?
-
03-07-2019 - |
Domanda
Aggiornamento importante
Dalla versione 1 dell'anteprima 1 di MVC 2.0 questa funzione è stata implementata come parte del framework stesso sotto forma di aree. Maggiori dettagli disponibili sul blog di Phil Haack qui
Ho un controller chiamato ListManagerController. Questo controller contiene un metodo ActionResult chiamato Index (). Quando faccio clic con il tasto destro su Index in Visual Studio e seleziono Aggiungi vista, la nuova vista viene creata in / Views / ListManager / Index.
Tuttavia, voglio che la vista Indice e tutte le viste successive vengano create in / Viste / Gestisci / ListManager /. Come lo farei?
Modifica : è stato sottolineato che questa domanda è un duplicato della domanda pubblicata qui . Sembra che inizialmente le mie capacità di ricerca mi abbiano deluso.
Soluzione
La posizione delle viste è legata alla ViewFactory in uso. I motori di visualizzazione dei moduli web AFAIK non supportano le aree [Gestisci nel tuo esempio].
Spark supporta questo ed è molto pulito, puoi anche mescolare e abbinare moduli web e visualizzazioni spark in modo da donare devi ricreare tutte le tue visualizzazioni.
AGGIORNAMENTO: Sembra che Phil Haack abbia un post di blog su come raggiungere questo obiettivo. Il suo codice è per RC, ma penso che dovrebbe compilare bene contro ASP.NET MVC RTM.
Altri suggerimenti
So che hai già accettato una risposta, ma ecco cosa mi è venuto in mente mentre sperimentavo la stessa idea, con l'aiuto di il post di Phil Haack .
Per prima cosa devi avere il tuo ViewEngine per cercare le cartelle in Visualizza cartella. Qualcosa del genere: (Noterai che assomiglia molto al prefisso di Phil Haack)
public class TestViewEngine : WebFormViewEngine
{
public TestViewEngine()
: base()
{
MasterLocationFormats = new[] {
"~/Views/{1}/{0}.master",
"~/Views/Shared/{0}.master"
};
ViewLocationFormats = new[] {
"~/{0}.aspx",
"~/{0}.ascx",
"~/Views/{1}/{0}.aspx",
"~/Views/{1}/{0}.ascx",
"~/Views/Shared/{0}.aspx",
"~/Views/Shared/{0}.ascx"
};
PartialViewLocationFormats = ViewLocationFormats;
}
public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
ViewEngineResult rootResult = null;
//if the route data has a root value defined when mapping routes in global.asax
if (controllerContext.RouteData.Values.ContainsKey("root")) {
//then try to find the view in the folder name defined in that route
string rootViewName = FormatViewName(controllerContext, viewName);
rootResult = base.FindView(controllerContext, rootViewName, masterName, useCache);
if (rootResult != null && rootResult.View != null) {
return rootResult;
}
//same if it's a shared view
string sharedRootViewName = FormatSharedViewName(controllerContext, viewName);
rootResult = base.FindView(controllerContext, sharedRootViewName, masterName, useCache);
if (rootResult != null && rootResult.View != null) {
return rootResult;
}
}
//if not let the base handle it
return base.FindView(controllerContext, viewName, masterName, useCache);
}
private static string FormatViewName(ControllerContext controllerContext, string viewName) {
string controllerName = controllerContext.RouteData.GetRequiredString("controller");
string root = controllerContext.RouteData.Values["root"].ToString();
return "Views/" + root + "/" + controllerName + "/" + viewName;
}
private static string FormatSharedViewName(ControllerContext controllerContext, string viewName) {
string root = controllerContext.RouteData.Values["root"].ToString();
return "Views/" + root + "/Shared/" + viewName;
}
}
Quindi nel Global.asax
sostituisci il ViewEngine predefinito con quello personalizzato, su Application_Start
:
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new TestViewEngine());
Ora quando si definiscono le rotte in Global.asax
, è necessario impostare un valore root
che indica la cartella da cercare in Visualizza cartelle in questo modo:
routes.MapRoute(
"ListManager",
"ListManager/{action}/{id}",
new { controller = "ListManager", action = "Index", id = "", root = "Manage" }
);
Questa domanda è MOLTO una ripetizione di questa domanda
quindi citerò la mia risposta a questa qui.
Ho trovato una soluzione diversa che non mi imponeva di fare il mio visualizza il motore.
In sostanza, volevo mantenere MVC come & Quot; Convention " guidato il più possibile, ma io volevo ancora organizzare tutto il mio & Quot; Admin " visualizzazioni in ~ / Views / Admin cartella.
Esempio:
- ~ / Vista / Amministratore / Utente /
- ~ / Vista / Amministratore / News /
- ~ / Vista / Amministratore / Blog /
La mia soluzione era quella di creare una nuova base classe per il mio amministratore specifico controllori e "force" il percorso verso la vista per quel controller.
Ho un post sul blog e un codice di esempio qui: Organizza le tue opinioni in ASP.Net MVC