ASP.NET MVC percorsi predefiniti accessibili tramite percorsi zona
-
26-09-2019 - |
Domanda
Finora (per brevità) ho una rotta in global.asax registrati in questo modo:
routes.Add(new LowercaseRoute("{action}/{id}", new MvcRouteHandler())
{
Defaults = new RouteValueDictionary(new { controller = "Home", action = "Index", id = UrlParameter.Optional }),
DataTokens = rootNamespace
});
Dove "RootNamespace" è
var rootNamespace = new RouteValueDictionary(new { namespaces = new[] { "MyApp.Web.Controllers" } });
LowercaseRoute eredita dal percorso e fa solo tutti i percorsi in minuscolo. Ho anche un'area registrati in questo modo:
context.Routes.Add(new LowercaseRoute("admin/{controller}/{action}/{id}", new MvcRouteHandler())
{
Defaults = new RouteValueDictionary(new { action = "List", id = UrlParameter.Optional }),
DataTokens = adminNamespace
});
Dove AdminNamespace è un altro spazio dei nomi, stessa idea come nel percorso di default, ma con lo spazio dei nomi a destra. Questo funziona bene, posso accedere agli URL che assomigliano a questo:
http://example.com/contact <- default route, "Home" controller
http://example.com/admin/account <- area route, "Account" controller, default "List" action
Il problema è che questo
http://example.com/admin/home/contact
funziona anche. Non c'è nessun controller "casa" con un'azione di "contatto" sotto l'area "admin". Si tira giusta pagina da "/ contatto", ma con l'URL di essere "/ admin / home / contatto".
C'è un modo per evitare che ciò accada?
Grazie.
Soluzione
Date un'occhiata al codice per 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;
}
Nota in particolare la UseNamespaceFallback di token, che è impostato su false per impostazione predefinita. È necessario avere una logica simile, se si vuole limitare la ricerca a namespace della zona. (True = cercare lo spazio dei nomi corrente per il controller, e in mancanza Cerca tutti gli spazi dei nomi. False = la ricerca solo lo spazio dei nomi corrente.)