在ASP.NET MVC中,最核心的当属“路由系统”,而路由系统的核心则源于一个强大的System.Web.Routing.dll组件。

自己动手写一个简单的MVC框架(第二版)

  在这个System.Web.Routing.dll中,有一个最重要的类叫做UrlRoutingModule,它是一个实现了IHttpModule接口的类,在请求处理管道中专门针对ASP.NET MVC请求进行处理。首先,我们要了解一下UrlRoutingModule是如何起作用的。

  (1)IIS网站的配置可以分为两个块:全局 Web.config 和本站 Web.config。Asp.Net Routing属于全局性的,所以它配置在全局Web.Config 中,我们可以在如下路径中找到:“$\Windows\Microsoft.NET\Framework\版本号\Config\Web.config“

 <?xml version="1.0" encoding="utf-8"?>
 <!-- the root web configuration file -->
 <configuration>
     <system.web>
         <httpModules>
             <add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" />
         </httpModules>
    </system.web>
 </configuration>

  (2)通过在全局Web.Config中注册 System.Web.Routing.UrlRoutingModule,IIS请求处理管道接到请求后,就会加载 UrlRoutingModule类型的Init()方法。

PS : 在UrlRoutingModule中为请求处理管道中的第七个事件PostResolveRequestCache注册了一个事件处理方法:OnApplicationPostResolveRequestCache。从这里可以看出:ASP.NET MVC的入口在UrlRoutingModule,即订阅了HttpApplication的第7个管道事件PostResolveRequestCahce。换句话说,是在HtttpApplication的第7个管道事件处对请求进行了拦截

自己动手写一个简单的MVC框架(第二版)

  现在我们将ASP.NET MVC的请求处理分为两个重要阶段来看看:

 ①在第七个事件中创建实现了IHttpHandler接口的MvcHandler

  当请求到达UrlRoutingModule的时候,UrlRoutingModule取出请求中的Controller、Action等RouteData信息,与路由表中的所有规则进行匹配,若匹配,把请求交给IRouteHandler,即MVCRouteHandler。我们可以看下UrlRoutingModule的源码来看看,以下是几句核心的代码:

public virtual void PostResolveRequestCache(HttpContextBase context)
{
    // 通过RouteCollection的静态方法GetRouteData获取到封装路由信息的RouteData实例
    RouteData routeData = this.RouteCollection.GetRouteData(context);
    if (routeData != null)
    {
        // 再从RouteData中获取MVCRouteHandler
        IRouteHandler routeHandler = routeData.RouteHandler;
        ......
        if (!(routeHandler is StopRoutingHandler))
        {
            ......
            // 调用 IRouteHandler.GetHttpHandler(),获取的IHttpHandler 类型实例,它是由 IRouteHandler.GetHttpHandler获取的,这个得去MVC的源码里看
            IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext);
            ......
            // 合适条件下,把之前将获取的IHttpHandler 类型实例 映射到IIS HTTP处理管道中
            context.RemapHandler(httpHandler);
        }
    }
}
View Code

相关文章: