ASP.NET MVC可通过区域路径访问的默认路由

pbz*_*pbz 9 asp.net-mvc-routing asp.net-mvc-areas asp.net-mvc-3

到目前为止(为了简洁起见)我在global.asax中有一条路由如此注册:

routes.Add(new LowercaseRoute("{action}/{id}", new MvcRouteHandler())
  {
    Defaults = new RouteValueDictionary(new { controller = "Home", action = "Index", id = UrlParameter.Optional }),
    DataTokens = rootNamespace
  }); 
Run Code Online (Sandbox Code Playgroud)

"rootNamespace"的位置

var rootNamespace = new RouteValueDictionary(new { namespaces = new[] { "MyApp.Web.Controllers" } });
Run Code Online (Sandbox Code Playgroud)

LowercaseRoute继承自Route,只是使所有路径都为小写.我还有一个像这样注册的区域:

context.Routes.Add(new LowercaseRoute("admin/{controller}/{action}/{id}", new MvcRouteHandler())
  {
    Defaults = new RouteValueDictionary(new { action = "List", id = UrlParameter.Optional }),
    DataTokens = adminNamespace
  });
Run Code Online (Sandbox Code Playgroud)

adminNamespace是另一个名称空间,与默认路由中的名称相同,但具有正确的名称空间.这工作正常,我可以访问如下所示的URL:

http://example.com/contact  <- default route, "Home" controller
http://example.com/admin/account  <- area route, "Account" controller, default "List" action
Run Code Online (Sandbox Code Playgroud)

问题是这个

http://example.com/admin/home/contact
Run Code Online (Sandbox Code Playgroud)

也有效.在"admin"区域下没有"home"控制器,其中包含"联系"操作.它从"/ contact"中拉出右页,但URL为"/ admin/home/contact".

有没有办法防止这种情况发生?

谢谢.

Lev*_*evi 17

看一下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;
}
Run Code Online (Sandbox Code Playgroud)

请特别注意UseNamespaceFallback标记,默认情况下设置为false.如果要将搜索限制为区域的命名空间,则需要具有类似的逻辑.(True =搜索控制器的当前名称空间,并且无法搜索所有名称空间.False =仅搜索当前名称空间.)