ASP.NET MVC routes par défaut accessibles par des voies de la zone
-
26-09-2019 - |
Question
Jusqu'à présent (par souci de concision) J'ai un itinéraire dans global.asax enregistré comme ceci:
routes.Add(new LowercaseRoute("{action}/{id}", new MvcRouteHandler())
{
Defaults = new RouteValueDictionary(new { controller = "Home", action = "Index", id = UrlParameter.Optional }),
DataTokens = rootNamespace
});
Où "RootNamespace" est
var rootNamespace = new RouteValueDictionary(new { namespaces = new[] { "MyApp.Web.Controllers" } });
LowercaseRoute hérite de la route et fait juste tous les chemins minuscules. Je suis aussi un domaine enregistré comme ceci:
context.Routes.Add(new LowercaseRoute("admin/{controller}/{action}/{id}", new MvcRouteHandler())
{
Defaults = new RouteValueDictionary(new { action = "List", id = UrlParameter.Optional }),
DataTokens = adminNamespace
});
Où adminNamespace est un autre espace de noms, même idée que dans la route par défaut, mais avec l'espace de noms droit. Cela fonctionne très bien, je peux accéder à des URL qui ressemblent à ceci:
http://example.com/contact <- default route, "Home" controller
http://example.com/admin/account <- area route, "Account" controller, default "List" action
Le problème est que ce
http://example.com/admin/home/contact
fonctionne aussi. Il n'y a pas de commande « à domicile » avec une action « de contact » dans la zone « admin ». Il tire la bonne page de "/ contact" mais avec l'URL étant "/ admin / home / contact".
Y at-il moyen d'éviter que cela se produise?
Merci.
La solution
Jetez un oeil au code pour 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;
}
Note en particulier les UseNamespaceFallback jeton, qui est définie sur false par défaut. Vous devez avoir la même logique si vous voulez limiter la recherche à l'espace de noms de la région. (True = rechercher l'espace de noms en cours pour le contrôleur, et à défaut recherche tous les espaces de noms. False = recherche que l'espace de noms en cours.)