3.RouteTable类
我们所说的路由注册的本质就是创建相应的Route对象并将它加入到RouteTable的静态属性Routes表示的全局路由表。先看一下RouteTable,
public class RouteTable
{
public static RouteCollection Routes{get;}
}
可以看到RouteTable返回一个RouteCollection对象,显而易见全局路由表应该就在这个对象中。接下来看一下RouteCollection类,
public class RouteCollection : Collection<RouteBase> { //当我们调用下面3个方法时,会遍历集合中的每一个Route对象。针对每一个Route对象,同名的方法会被调用 //如果方法返回一个具体的RouteData或VirtualPathData对象,这个对象会直接作为方法的返回值。 //也就是说,只要遇到满足匹配的route对象,那么这个对象就会作为整个方法的返回值 //如果每个Route对象返回null,那么整个方法返回的就是null public RouteData GetRouteData(HttpContextBase httpContext); public VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values); public VirtualPathData GetVirtualPath(RequestContext requestContext, string name, RouteValueDictionary values);
//用于注册一个路由模板使路由系统可以忽略具有这个对应模式的URL public void Ignore(string url); public void Ignore(string url, object constraints); //路由映射,一共有5个重载的MapPageRoute方法 //这个方法与Ignore方法相反,它用于注册某个路径与路由模板之间的映射,其本质就是在本集合中添加一个Route对象 public Route MapPageRoute(string routeName, string routeUrl, string physicalFile); public Route MapPageRoute(string routeName, string routeUrl, string physicalFile, bool checkPhysicalUrlAccess); }
当我们在调用MapPageRoute方法时,它会将routeName参数作为对应Route对象的注册名称,这个名称和Route对象的映射关系存在一个属性Dictionary属性里,因此我们是可以通过名称拿到这个Route对象。
4.路由注册
路由注册的核心在于根据提供的路由规则(路由模板,约束,默认值等)来创建一个Route对象,然后添加到RouteTable。先看一个例子:
public static void RegisterRoutes(RouteCollection routes) { //指定默认值 var defaults = new RouteValueDictionary { { "areacode", "010" }, { "day", "2" } }; //基于正则表达式的约束 var constains = new RouteValueDictionary { { "areacode",@"0\d{2,3}" },{"day",@"[1-3]"} }; //表示对变量默认值的说明 var dataTokens = new RouteValueDictionary { { "defaultCity", "BeiJing" }, { "defaultDays", "2" } }; //注册路由 RouteTable.Routes.MapPageRoute("default", "{areacode}/{days}", "~/weather.aspx", false, defaults, constains, dataTokens); }
此时,当我们输入localhost:29323;localhost:29323/010;localhost:29323/010/2时,其效果是一样的。解析后的路由数据,如010,2等则存在RouteData.Values里面。其次,如果请求url不满足提供的正则表达式的约束,也是无法与路由对象匹配的。在constains变量中,还可以添加请求方式的约束:{"httpMethod",new HttpMethodConstraint("POST")}。
书上还强调:只有当Route.RouteExistingFiles为true,Route.RouteExistingFiles为true,Route.GetRouteData()返回匹配成功的RouteData对象时,RouteCollection.GetRouteData才能返回一个具体的RouteData对象,这个地方我还是没想明白为什么这样子。