10

到目前为止(为简洁起见),我在 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 是另一个命名空间,与默认路由中的想法相同,但具有正确的命名空间。这很好用,我可以访问如下所示的 URL:

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

也有效。“管理”区域下没有带有“联系”操作的“家庭”控制器。它从“/contact”中提取正确的页面,但 URL 为“/admin/home/contact”。

有什么办法可以防止这种情况发生吗?

谢谢。

4

1 回答 1

18

看一下 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 = 仅搜索当前命名空间。)

于 2011-01-06T09:06:43.080 回答