public class UrlRoutingModule : IHttpModule { _contextKey; _requestDataKey; private RouteCollection _routeCollection; UrlRoutingModule(); public UrlRoutingModule(); Dispose(); Init(HttpApplication application); private void OnApplicationPostResolveRequestCache(object sender, EventArgs e); [Obsolete()] PostMapRequestHandler(HttpContextBase context); PostResolveRequestCache(HttpContextBase context); void IHttpModule.Dispose(); void IHttpModule.Init(HttpApplication application); RouteCollection RouteCollection { get; set; } }
重点肯定在Init()方法。
图一:
注册HttpApplication对象的PostResolveRequestCache事件。
图二:
封装HttpContext,成为HttpContextWrapper对象
图三:
这部分代码是我们上述路由理论的代码实践,所以这段代码很重要,我们将代码拷贝出来:
PostResolveRequestCache(HttpContextBase context) { //1.传入当前上下文对象,得到与当前请求匹配的RouteData对象 RouteData routeData = this.RouteCollection.GetRouteData(context); if (routeData != null) { //2.从RouteData对象里面得到当前的RouteHandler对象。其实这里的RouteHandler属性对应就是一个MvcRouteHandler的对象。 IRouteHandler routeHandler = routeData.RouteHandler; ), new object[0])); if (!(routeHandler is StopRoutingHandler)) { //3.根据HttpContext和RouteData得到RequestContext对象 RequestContext requestContext = new RequestContext(context, routeData); context.Request.RequestContext = requestContext; //4.根据RequestContext对象得到处理当前请求的HttpHandler(MvcHandler)。 IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext); if (httpHandler == null) { object[] args = new object[] { routeHandler.GetType() }; ), args)); } if (httpHandler is UrlAuthFailureHandler) { )); UrlAuthorizationModule.ReportUrlAuthorizationFailure(HttpContext.Current, this); } context.RemapHandler(httpHandler); } } }
博主在主要的地方加上了注释。
代码释疑:这里有几点需要说明的。
1、HttpApplication对象的PostResolveRequestCache事件在MSDN上的解释是:在 ASP.NET 跳过当前事件处理程序的执行并允许缓存模块满足来自缓存的请求时发生。查阅相关资料发现,之所以在PostResolveRequestCache事件注册路由、匹配HttpHandler,是为了满足IIS6。可以参考Tom大叔的文章:。
2、 IRouteHandler routeHandler = routeData.RouteHandler; 这里的routeHandler实际上是一个MvcRouteHandler类型的对象,为什么这么说,我们来反编译下这个就会一目了然:
图一:
MvcRouteHandler实现了IRouteHandler接口。然后我们重点来看GetHttpHandler()方法得到的是哪个HttpHandler。
图二:
看到最后一句是不是立马就明白了。也就是说GetHttpHandler()这个方法决定了采用MvcHandler去处理当前的http请求。所以在上述 IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext); 这一句得到的就是一个MvcHandler的实例。
3、 context.RemapHandler(httpHandler); 这一句可以理解为将当前的请求上下文交给httpHandler这个对象去处理。
4、到这里,我们再反过来看前面的MVC的原理就完全明朗了。
四、总结