Area的使用函数
Area--->AreaRegister.RegisterAllArea()与Area区域的解析学习
学习本文建议先看下另外一篇文章(Area--->AreaRegister.RegisterAllArea()与Area区域的解析),此篇文章着重解析AreaRegistrationContext.MapRoute函数。ui
接着上一篇文章的末尾进行阐述,上一篇文章的末尾为:this
Area的注册过程的第一步先找到全部继承或实现AreaRegistration类的类并序列化以后保存进缓存文件。接着才是重头戏(MapRoute)进行路由注册。url
在AreaRegistrationContext中一样存在同名的MapRoute函数。spa
1 public Route MapRoute(string name, string url, string[] namespaces) 2 { 3 return this.MapRoute(name, url, null, namespaces); 4 } 5 6 public Route MapRoute(string name, string url, object defaults, object constraints) 7 { 8 return this.MapRoute(name, url, defaults, constraints, null); 9 } 10 11 public Route MapRoute(string name, string url, object defaults, string[] namespaces) 12 { 13 return this.MapRoute(name, url, defaults, null, namespaces); 14 } 15 16 public Route MapRoute(string name, string url, object defaults, object constraints, string[] namespaces) 17 { 18 if ((namespaces == null) && (this.Namespaces != null)) 19 { 20 namespaces = this.Namespaces.ToArray<string>(); 21 } 22 Route route1 = this.Routes.MapRoute(name, url, defaults, constraints, namespaces); 23 route1.DataTokens["area"] = this.AreaName; 24 bool flag = (namespaces == null) || (namespaces.Length == 0); 25 route1.DataTokens["UseNamespaceFallback"] = flag; 26 return route1; 27 }
在上部代码中能够看到,整个代码的核心最终仍是引用的Routes.MapRoute进行路由的注册。code
Routes就是一个RouteCollection,此处的Routes还须要追溯到上一篇文章
下面为AreaRegistrationContext的构造函数,经过构造函数完成This.Routes的初始化赋值。
1 public AreaRegistrationContext(string areaName, RouteCollection routes, object state) 2 { 3 this._namespaces = new HashSet<string>(StringComparer.OrdinalIgnoreCase); 4 if (string.IsNullOrEmpty(areaName)) 5 { 6 throw System.Web.Mvc.Error.ParameterCannotBeNullOrEmpty("areaName"); 7 } 8 if (routes == null) 9 { 10 throw new ArgumentNullException("routes"); 11 } 12 this.AreaName = areaName; 13 this.Routes = routes; 14 this.State = state; 15 }
咱们接着来看Routes.MapRoute的代码
上面代码实例化一个Route并对属性进行赋值,其中Constraints和DataTokens值都同样,都是new RouteValueDictionary()。因为route.Constraints为空,则ConstraintValidation.Validate(route)不会运行函数内部代码。此扩展函数最后将信息Add进当前Routes,并返回路由信息route。
最后对Routes.DataTokens(RouteValueDictionary)添加信息,并返回Route。
针对某个Area的路由映射是经过相应的AreaRegistration进行注册的,具体来讲是在AreaRegistration的RegisterArea方法中调用AreaRegistrationContext对象的MapRoute方法进行注册的。若是在调用MapRoute方法中指定了表示命名空间的字符串,将自动做为注册的路由对象的命名空间,不然会将表示AreaRegistration所在命名空间的字符串加上"."后缀做为路由对象的命名空间。
这里说的路由对象的命名空间指的是经过Route对象的DataTokens属性表示的RouteValueDictionary对象中Key为Namespaces的字符串数组,而该字符串最终会转移到生成的RouteData的DataTokens中。
除此以外,在调用AareaRegistrationContext的MapRoute方法时,还会在注册Route对象DataTokens中添加一个Key为UseNamespaceFallback的条目表示是否采用后背命名空间 对Controller进行解析。若是注册对象具备命名控件(调用MapRoute方法时指定了命名空间或对应的AreaRegistration类型定义在某个命名空间中),该条目值为false。
在解析Controller类型过程当中,会先经过RouteData包含的命名空间来解析Controller类型。若是Controller类型解析失败,则经过包含RouteData的DataTokens属性key为useNamespaceFallback值来判断是否使用后背命名空间来进行解析。若是为true,则经过当前ControllerBuilder的命名空间解析,若是失败则忽略命名空间直接采用类型名称进行匹配,不然直接抛出异常。