大多數作過.NET WEB FORM的人,第一次接觸ASP.NET MVC, 對路由可能很陌生,在他們的潛意識裏訪問一個.Net Web 應用程序是這樣的。瀏覽器
從訪問地址咱們能看出,對應的是一個物理地址Index.aspx文件,是一對一的物理關係。假如咱們在後期更改文件名稱或移動文件位置後,頁面地址也會發生改變,用URL地址再訪問時頁面會失效,且報404頁面不存在的錯誤。工具
其實路由並非ASP.NET MVC特有的,其實在WEB.FORM開發裏面就有了。只是咱們沒有去深究它。然而隨着時間的推移,咱們的URL再也不是一個.aspx頁面了,而是像{xxxx}/{xxx}的URL形式來對應一個aspx文件。源碼分析
所以,咱們能夠知道路由能夠解決URL與物理文件分離,它維繫着URL與物理文件之間的關聯映射,使URL和物理文件的改變,都不會受影響。this
1. 新建一個ASP.NET WEB應用程序,而後選擇空項目模板。並新建一個Dafault.aspx、Global.asax文件。spa
2. 打開Global文件,在Application_Start方法中添加路由信息。code
1) 「List'」路由名稱,能夠理解爲這個路由的名稱是List,也就是路由的標識符。orm
2) 「Blog/{Name}/{Category}」表示以一個什麼樣的URL格式訪問default.aspx頁面,其中{Name}和{Category}表示路由變量。對象
3) 「Default.aspx」:要訪問的實際頁面,也就是訪問URL實際要映射的物理文件。blog
4) 「 new RouteValueDictionary() { { "Name", "*" }, { "Category", "*" } }:表示路由變量默認值。當咱們在URL中沒有指定Name和Category,那麼將採用默認值*.路由
5) 「 new RouteValueDictionary() { { "ID", "*" } }:路由的Token值,能夠理解爲一個附加的路由值。
3. 咱們在路由集合中添加了一個名爲「List」,訪問格式爲「Blog/{Name}/{Category}」的URL,實際訪問頁面爲Default.aspx,默認路由變量Name="*",Category="*"的路由。當咱們在瀏覽器中輸入http://lcoalhost/Blog
RouteTable.Routes.MapPageRoute背後到底發生了什麼呢?下面咱們來分析源碼:
注:使用ILSpy工具進行源碼解析:下載地址
RouteTable.cs
using System; using System.Runtime.CompilerServices; namespace System.Web.Routing { [TypeForwardedFrom("System.Web.Routing, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35")] public class RouteTable { private static RouteCollection _instance = new RouteCollection(); //單列模式 public static RouteCollection Routes //屬性,返回RouteCollection對象集合 { get { return RouteTable._instance; } } } }
RouteCollection.cs類中的MapPageRoute方法
public Route MapPageRoute(string routeName, string routeUrl, string physicalFile, bool checkPhysicalUrlAccess, RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens) { if (routeUrl == null) //路由格式不能爲空,不然會報routeRul異常。上面例子中指的是 "Blog/{Name}/{Category}" { throw new ArgumentNullException("routeUrl"); }
// 實例一個路由對象,根據設置的路由信息,添加到路由集合RouteCollection中 Route route = new Route(routeUrl, defaults, constraints, dataTokens, new PageRouteHandler(physicalFile, checkPhysicalUrlAccess)); this.Add(routeName, route); return route; }