ASP.NET MVC Rutas predeterminadas accesibles a través de rutas de área
-
26-09-2019 - |
Pregunta
Hasta ahora (por brevedad) tengo una ruta en Global.asax registrada así:
routes.Add(new LowercaseRoute("{action}/{id}", new MvcRouteHandler())
{
Defaults = new RouteValueDictionary(new { controller = "Home", action = "Index", id = UrlParameter.Optional }),
DataTokens = rootNamespace
});
Donde está "RootNamespace"
var rootNamespace = new RouteValueDictionary(new { namespaces = new[] { "MyApp.Web.Controllers" } });
LowerCaseroute hereda de la ruta y solo hace que todas las rutas en minúsculas. También tengo un área registrada como esta:
context.Routes.Add(new LowercaseRoute("admin/{controller}/{action}/{id}", new MvcRouteHandler())
{
Defaults = new RouteValueDictionary(new { action = "List", id = UrlParameter.Optional }),
DataTokens = adminNamespace
});
Donde AdminnamesSpace es otro espacio de nombres, la misma idea que en la ruta predeterminada, pero con el espacio de nombres correcto. Esto funciona bien, puedo acceder a URL que se ven así:
http://example.com/contact <- default route, "Home" controller
http://example.com/admin/account <- area route, "Account" controller, default "List" action
El problema es que esto
http://example.com/admin/home/contact
También funciona. No hay un controlador de "hogar" con una acción de "contacto" en el área "administrador". Extrae la página correcta de "/Contact" pero con URL es "/Admin/Home/Contact".
¿Hay alguna forma de evitar que esto suceda?
Gracias.
Solución
Eche un vistazo al código para areareGistrationContext.Maproute:
public Route MapRoute(string name, string url, object defaults, object constraints, string[] namespaces) {
if (namespaces == null && Namespaces != null) {
namespaces = Namespaces.ToArray();
}
Route route = Routes.MapRoute(name, url, defaults, constraints, namespaces);
route.DataTokens["area"] = AreaName;
// disabling the namespace lookup fallback mechanism keeps this areas from accidentally picking up
// controllers belonging to other areas
bool useNamespaceFallback = (namespaces == null || namespaces.Length == 0);
route.DataTokens["UseNamespaceFallback"] = useNamespaceFallback;
return route;
}
Tenga en cuenta en particular el UsenamespaceFallback Token, que se establece en falso por defecto. Debe tener una lógica similar si desea limitar la búsqueda al espacio de nombres del área. (True = Buscar el espacio de nombres actual para el controlador y fallar que busque todos los espacios de nombres. False = Buscar solo el espacio de nombres actual).