大多数作过.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; }