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

时间:2011-01-06 06:12:36

标签: asp.net-mvc-3 asp.net-mvc-routing asp.net-mvc-areas

到目前为止(为了简洁起见)我在global.asax中有一条路由,如下所示:

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

“rootNamespace”是

var rootNamespace = new RouteValueDictionary(new { namespaces = new[] { "MyApp.Web.Controllers" } });

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

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

其中adminNamespace是另一个名称空间,与默认路由中的构思相同,但具有正确的名称空间。这很好用,我可以访问如下所示的网址:

http://example.com/contact  <- default route, "Home" controller
http://example.com/admin/account  <- area route, "Account" controller, default "List" action

问题是这个

http://example.com/admin/home/contact

也有效。在“admin”区域下没有“home”控制器,其中包含“联系”操作。它从“/ contact”中提取右页,但URL为“/ admin / home / contact”。

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

感谢。

1 个答案:

答案 0 :(得分: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;
}

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