现在我们对本例的路由注册代码作了如下的修改,为注册的路由对象指定了两个命名空间(分别是两个HomeContrller所在的命名空间),运行我们的程序依然会得到如第一张图所示的错误。
- public class MvcApplication : System.Web.HttpApplication
- {
- public static void RegisterRoutes(RouteCollection routes)
- {
- routes.MapRoute(
- name: "Default",
- url: "{controller}/{action}/{id}",
- defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
- namespaces: new string[] { "Artech.MvcApp", "Artech.MvcApp.Controllers" }
- );
- }
- protected void Application_Start()
- {
- //其他操作
- RegisterRoutes(RouteTable.Routes);
- }
- }
针对Area的路由对象的命名空间
针对某个Area的路由映射是通过相应的AreaRegistration进行注册的,具体来说是在AreaRegistration的RegisterArea方法中调用AreaRegistrationContext对象的MapRoute方法进行注册的。如果在调用MapRoute方法中指定了表示命名空间的字符串,将自动作为注册的路由对象的命名空间,否则会将表示AreaRegistration所在命名空间的字符串加上“.*”后缀作为路由对象的命名空间。这里所说的“路由对象的命名空间”指的就是通过Route对象的DataTokens属性表示的RouteValueDictionary对象中Key为“Namespaces”的字符串数组,而该字符串最终会转移到生成的RouteData的DataTokens中。
除此之外,在调用AreaRegistrationContext的MapRoute方法时还会在注册Route对象DataTokens中添加一个Key为“UseNamespaceFallback”的条目表示是否采用后备命名空间对Controller类型进行解析。如果注册对象具有命名空间(调用MapRoute方法时指定了命名空间或者对应的AreaRegistration类型定义在某个命名空间中),该条目的值为False;否则为True。该条目同样反映在通过该Route对象生成的RouteData对象的DataTokens属性中。[关于ASP.NET MVC路由,在我的文章《ASP.NET MVC路由扩展:路由映射》中具有详细的介绍]
在解析Controller真实类型的过程中,会先通过RouteData包含的命名空间来解析Controller类型。如果Controller类型解析失败,则通过包含在通过RouteData的DataTokens属性表示的RouteValueDictionary对象中的这个UseNamespaceFallback值来判断是否使用“后备”命名空间进行解析。具体来说,如果该值为True或者不存在,则先通过当