2011-01-06 157 views
9

到目前为止(为简便起见)我在Global.asax的一个途径注册这样的:ASP.NET MVC的缺省路由通过区域内路由访问

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 

也适用。在“管理”区域下没有“家”控制器与“联系”行动。它从“/ contact”中拉出正确的页面,但URL是“/ admin/home/contact”。

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

谢谢。

回答

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 =仅搜索当前名称空间)

+1

将“UseNamespaceFallback = false”添加到管理区域DataTokens字典解决了该问题。谢谢! – pbz 2011-01-06 18:36:00