Rotas padrão do ASP.NET MVC acessíveis através de rotas de área
-
26-09-2019 - |
Pergunta
Até agora (para a brevidade), tenho uma rota no Global.asax registrado assim:
routes.Add(new LowercaseRoute("{action}/{id}", new MvcRouteHandler())
{
Defaults = new RouteValueDictionary(new { controller = "Home", action = "Index", id = UrlParameter.Optional }),
DataTokens = rootNamespace
});
Onde "rootnamespace" está
var rootNamespace = new RouteValueDictionary(new { namespaces = new[] { "MyApp.Web.Controllers" } });
O LowerCaseroute herda da rota e apenas torna todos os caminhos minúsculos. Eu também tenho uma área registrada assim:
context.Routes.Add(new LowercaseRoute("admin/{controller}/{action}/{id}", new MvcRouteHandler())
{
Defaults = new RouteValueDictionary(new { action = "List", id = UrlParameter.Optional }),
DataTokens = adminNamespace
});
Onde o AdminNamesPace é outro espaço para nome, a mesma idéia da rota padrão, mas com o espaço para nome certo. Isso funciona bem, eu posso acessar URLs que se parecem com o seguinte:
http://example.com/contact <- default route, "Home" controller
http://example.com/admin/account <- area route, "Account" controller, default "List" action
O problema é que isso
http://example.com/admin/home/contact
também funciona. Não existe um controlador "home" com uma ação de "contato" na área de "admin". Ele puxa a página certa de "/contato", mas com o URL sendo "/admin/home/contact".
Existe alguma maneira de impedir que isso aconteça?
Obrigado.
Solução
Dê uma olhada no 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;
}
Note em particular o Usenamespacefallback Token, que é definido como falso por padrão. Você precisa ter uma lógica semelhante se deseja limitar a pesquisa ao espaço para nome da área. (True = pesquise o espaço de nome atual para o controlador e falhando nessa pesquisa em todos os espaços para nome. False = pesquise apenas no espaço de nome atual.)