¿Cómo especificar la ubicación donde se creará una vista Mvc para un controlador Mvc?
-
03-07-2019 - |
Pregunta
Actualización importante
Desde el lanzamiento de MVC 2.0 Preview 1, esta característica se ha implementado como parte del propio marco en forma de Áreas. Más detalles disponibles en el blog de Phil Haack aquí
Tengo un controlador llamado ListManagerController. Este controlador contiene un método ActionResult llamado Index (). Cuando hago clic derecho en Index en Visual Studio y selecciono Agregar vista, la nueva vista se crea en / Vistas / ListManager / Índice.
Sin embargo, quiero que la vista de índice y todas las vistas posteriores se creen en / Vistas / Administrar / ListManager /. ¿Cómo lograría esto?
Editar : se señaló que esta pregunta es un duplicado de la pregunta publicada aquí . Parece que mis habilidades de búsqueda me fallaron inicialmente.
Solución
La ubicación de las vistas está vinculada al ViewFactory que está utilizando. AFAIK los motores de visualización de formularios web no admiten áreas [Administrar en su ejemplo].
Spark admite esto y está muy limpio, también puedes mezclar y combinar formularios web y generar vistas para que no No tienes que recrear todas tus vistas.
ACTUALIZACIÓN: parece que Phil Haack tiene un blog post sobre cómo lograr esto. Su código es para el RC, pero creo que debería compilarse bien contra ASP.NET MVC RTM.
Otros consejos
Sé que ya aceptaste una respuesta, pero esto es lo que se me ocurrió al experimentar con la misma idea, con la ayuda de la publicación de Phil Haack .
Primero necesita tener su propio ViewEngine para buscar carpetas en la carpeta Ver. Algo como esto: (Notarás que se parece mucho al código de áreas de 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;
}
}
Luego, en su Global.asax
, reemplace el ViewEngine predeterminado por el personalizado, en Application_Start
:
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new TestViewEngine());
Ahora, cuando está definiendo rutas en Global.asax
, debe establecer un valor de root
que indique la carpeta que debe buscar en las carpetas de vista de la siguiente manera:
routes.MapRoute(
"ListManager",
"ListManager/{action}/{id}",
new { controller = "ListManager", action = "Index", id = "", root = "Manage" }
);
Esta pregunta es MUY una repetición de esta pregunta
así que citaré mi respuesta a esa aquí.
Se me ocurrió una solución diferente Eso no requería que yo hiciera mi propio rollo. motor de visualización.
Básicamente, quería mantener MVC como " Convención " conducido como sea posible, pero yo Todavía quería organizar todo mi " Admin " vistas bajo el ~ / Vistas / Admin carpeta.
Ejemplo:
- ~ / Views / Admin / User /
- ~ / Views / Admin / News /
- ~ / Views / Admin / Blog /
Mi solución fue crear una nueva base clase para mi administrador especifico controladores y " fuerza " el camino hacia la vista para ese controlador.
Tengo una publicación en el blog y un código de muestra aquí: Organiza tus vistas en ASP.Net MVC