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的命名空間解析,若是失敗則忽略命名空間直接採用類型名稱進行匹配,不然直接拋出異常。