MVC中的URL路由(一)


  URL路由系統通過對請求地址進行解析從而得到以目標Controller名稱為核心的路由數據。Url路由系統最初是為了實現請求url與物理文件路徑分離而建立的,MVC的Url Route是將Url地址與物理文件映射轉移到了目標Controller的映射。

Url路由不是ASP.NET MVC特有的,而是建立在ASP.NET上面的,MVC的只是對這個路由的拓展使用(asp.net也開始使用這拓展了)。

 

  我們在App_Start文件夾中找到RouteConfig.cs的文件,打開看

 1         public static void RegisterRoutes(RouteCollection routes)
 2         {
 3             routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
 4 
 5             routes.MapRoute(
 6                 name: "Default",
 7                 url: "{controller}/{action}/{id}",
 8                 defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
 9             );
10         }

  大體可以猜出什么意思,url那一欄地址中第一個是controller,第二個是action,第三個是參數id,defaults是默認的參數,然后在Global.asax對該路由進行注冊。

  

1         protected void Application_Start()
2         {
3             AreaRegistration.RegisterAllAreas();
4             FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
5             RouteConfig.RegisterRoutes(RouteTable.Routes);
6             BundleConfig.RegisterBundles(BundleTable.Bundles);
7         }

 

  

  簡單來說路由的任務:檢查請求的URL,找出當前請求的是哪個controller中的哪個action,並且有無帶了什么參數過來。

 

  那好,我們來分析一下請求一個地址的時候,路由系統發生了什么事情?我們先來大膽的猜一下:類似於網絡設備的路由器,它會有一個路由表,根據我們配置的規則對端口過來的數據進行轉發,這張表里就記錄了匹配規則跟處理的程序,當一個數據包過來的時候,去這張表里面尋找所相應的發送地址,找到的話路由系統就將這數據包發往哪個對應的地址里面。

 

  按照上面邏輯的話,我們先來找找匹配的規則在哪里加上來的,我們在上面的靜態方法里面看到有一個RouteCollection的東西,進去看看里面有啥?

  

  發現了一個MapPageRoute的方法

  

 1         //
 2         // 摘要: 
 3         //     提供用於定義 Web 窗體應用程序的路由的方法。
 4         //
 5         // 參數: 
 6         //   routeName:
 7         //     路由的名稱。
 8         //
 9         //   routeUrl:
10         //     路由的 URL 模式。
11         //
12         //   physicalFile:
13         //     路由的物理 URL。
14         //
15         // 返回結果: 
16         //     將添加到路由集合的路由。
17         public Route MapPageRoute(string routeName, string routeUrl, string physicalFile);

 

  

  可以看到我們調用RouteCollection的MapPageRoute方法將某個物理文件路徑映射到一個URL模板上,這個過程其實就是基於指定的url模板創建一個路由對象,並且將他添加到這個全局路由表中,那程序是在哪里有個Add的入口呢?不小心在RouteCollection里面發現了一個Add的方法

 

  

 1         // 摘要: 
 2         //     將路由添加到 System.Web.Routing.RouteCollection 對象的結尾,並為路由分配指定的名稱。
 3         //
 4         // 參數: 
 5         //   name:
 6         //     標識路由的值。 該值可為 null 或空字符串。
 7         //
 8         //   item:
 9         //     要添加到集合結尾的路由。
10         //
11         // 異常: 
12         //   System.ArgumentNullException:
13         //     item 為 null。
14         //
15         //   System.ArgumentException:
16         //     name 已在集合中使用。
17         public void Add(string name, RouteBase item);

 

  

  可以看到這里添加了一個Routebase的東西,我們點擊去看看是什么來頭?

 

  

 1     // 摘要: 
 2     //     用作表示 ASP.NET 路由的所有類的基類。
 3     [TypeForwardedFrom("System.Web.Routing, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35")]
 4     public abstract class RouteBase
 5     {
 6         // 摘要: 
 7         //     初始化該類供繼承的類實例使用。 此構造函數只能由繼承的類調用。
 8         protected RouteBase();
 9 
10         // 摘要: 
11         //     獲取或設置一個值,該值指示 ASP.NET 路由操作是否應處理與現有文件匹配的 URL。
12         //
13         // 返回結果: 
14         //     如果 ASP.NET 路由操作處理所有請求(甚至包括與現有文件匹配的請求),則為 true;否則為 false。 默認值為 false。
15         public bool RouteExistingFiles { get; set; }
16 
17         // 摘要: 
18         //     當在派生類中重寫時,會返回有關請求的路由信息。
19         //
20         // 參數: 
21         //   httpContext:
22         //     一個對象,封裝有關 HTTP 請求的信息。
23         //
24         // 返回結果: 
25         //     一個對象,包含路由定義的值(如果該路由與當前請求匹配)或 null(如果該路由與請求不匹配)。
26         public abstract RouteData GetRouteData(HttpContextBase httpContext);
27         //
28         // 摘要: 
29         //     當在派生類中重寫時,會檢查路由是否與指定值匹配,如果匹配,則生成一個 URL,然后檢索有關該路由的信息。
30         //
31         // 參數: 
32         //   requestContext:
33         //     一個對象,封裝有關所請求的路由的信息。
34         //
35         //   values:
36         //     一個包含路由參數的對象。
37         //
38         // 返回結果: 
39         //     一個對象(包含生成的 URL 和有關路由的信息)或 null(如果路由與 values 不匹配)。
40         public abstract VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values);
41     }

 

  我們看到了兩個抽象方法:GetRouteData與GetVirtualPath,當一個請求過來的時候,它們都會去根據URL模板的模式與代表請求地址的URL地址進行匹配,如果匹配失敗返回null,成功的話,GetRouteData會得到一個封裝了路由信息的RouteData對象,而GetVirtualPath則會生成一個URL,該URL被封裝成VirtualPathData對象進行返回。

 

  那通過以上猜測,我們知道了路由系統物理文件路徑添加到一個全局的路由表中,並傳入給定的參數調用同名方法去找到一個與指定請求URL相匹配的路由對象,並返回相應的RouteData和VirtualPathData對象。

 

  好了,簡單的Url就寫就這里了,稍后會對下一步進行詳解,盡請期待!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM