主题 | 概要 |
---|---|
Asp.net路由 | Asp.net路由原理初探 |
编辑 | 时间 |
新建 | 20170714 |
序号 | 参考资料 |
1 | http://wangqingpei557.blog.51cto.com/1009349/1312422/ |
2 | https://github.com/aspnet/Routing(路由源码) |
路由配置
才接触asp.net,希望能一个专题一个专题的把问题搞明白深入些。
从最简单的RouteConfig开始,RegisterRoutes静态方法进行路由注册:
MapPageRoute方法是为了使Url地址与WebForm页面物理地址隔离,MapRoute方法是MVC固定的格式。
配置好后,在Global.asax中进行注册:
注意这里的参数,RouteTable.Routes属性是一个RouteCollection。
而注意这里的形参routes实际传入的是RouteTable.Routes:
所以不管是WebForms的路由,还是MVC的路由,都是存放在RouteTable.Routes。
把路由信息存放到RouteTable.Routes里了,但是在什么地方处理取用它呢?
UrlRoutingModule—路由对象模型的入口
这里面的关键步骤是:
UrlRoutingModule绑定Application事件:
protected virtual void Init(HttpApplication application)
{
application.PostResolveRequestCache += PostResolveRequestCache;
}
PostResolveRequestCache事件是“ASP.NET 将绕过当前事件处理程序的执行,并允许缓存模块以处理从缓存请求时发生”。更直白的理解就是缓存模块处理从缓存请求时,发生此事件。
在PostResolverRequestCache方法中,该方法调用了本地内部的一个同名方法:
void PostResolveRequestCache(object o, EventArgs e)
{
var app = (HttpApplication)o;
PostResolveRequestCache(new HttpContextWrapper(app.Context));
}
然后实例化了一个HttpContextWrapper包装对象,传入该同名方法:
public virtual void PostResolveRequestCache(HttpContextBase context)
{
var rd = RouteCollection.GetRouteData(context);
//(1)匹配RouteData对象,后面分析;
var rc = new RequestContext(context, rd);
//(2)封装计算出来的RouteData对象和当前HttpRequest对象;
IHttpHandler http = rd.RouteHandler.GetHttpHandler(rc);
//(3)使用(1)步骤计算出来的当前RouteData对象中的RouteHander属性获取路由处理程序IHttpHander接口;
context.Request.RequestContext = rc;
context.RemapHandler(http);
}
这里面主要分为三个步骤:
1)、根据请求,从前面注册的路由表中,匹配到RouteData对象;
2)、根据RouteData和HttpContext封装一个RequestContext;
3)、根据RouteData的RouteHandler属性获取处理程序IHttpHander接口;
这里要注意的是RouteHandler属性,实际上是一个IRouteHandler接口,根据依赖倒置原则,如果匹配的是MVC路由,就是MVCRouteHandler,如果匹配的是Webform就是Webform的RouteHandler,也可以自定义RouteHandler。
这里迷惑的可能是IRouteHandler 、IHttpHandler两个接口之间的关系,IRouteHandler只有一个方法:
只有实现了这个方法,才能得到正确的HttpHandler。