在ASP.NET WebForms框架下,我们的请求都是.../xx.aspx格式的,URL代表磁盘上的物理文件,可以明确站点上有一个xx.aspx的文件;而ASP.NET MVC则是把方法映射到某个类的方法调用,而不是直接映射到磁盘上的某个物理文件。
今天来谈谈ASP.NET MVC的路由机制,因为这是理解MVC原理不可逾越的鸿沟。
当我们收到一个URL的请求时,服务端收到请求,主要经历以下几个步骤:
1.请求被UrlRoutingModule部件拦截
2.封装请求上下文HttpContext,成为HttpContextWrapper对象。
3.根据当前的HttpContext,从Routes集合中得到与当前请求URL相符合的RouteData对象。
4.将RouteData与HttpContext请求封装成一个RequestContext对象。
5.根据RequestContext对象,从RouteData的RouteHandler中获取IHttpHandler(MVC里面会有一个IHttpHandler的实现类MvcHandler)。
6.执行IHttpHandler(MvcHandler),然后就是通过反射激活具体的controller,执行具体的action。

1.整个过程有两个核心的组件:UrlRoutingModule和MvcHandler,上文提到的各个过程都和两个组件有紧密的联系。而这两个组件分别继承至IHttpModule和IHttpHandler接口。
2.UrlRoutingModule的作用可以理解为通过一系列的与路由相关的组件去解析当前请求的Controller与Action名称。
3.MvcHandler的作用就更加直接,上述通过拦截组件得到了请求的Controller和Action的名称,MvcHandler组件将当前请求的Controller名称反射得到对应的控制器对象,然后执行对应的Action方法。
4.联合这两个组件来理解,UrlRoutingMudule组件的主要作用是解析当前的Controller与Action名称,MvcHandler的作用是将得到的Controller名称激活,得到具体的Controller对象,然后执行对应的Action方法。
==============================================================
在asp.net的页面生命周期里面,一共有24个管线事件,其中有两个重要的角色分别是HttpHandler和HttpModule,本篇重点讨论IHttpHandler。
这里的HttpHandler我们称为所有实现IHttpHandler接口的统称,先来看看这个接口的定义:
public interface IHttpHandler
{
// 定义一个处理当前http请求的方法
void ProcessRequest(HttpContext context);
// 指示当前实例是否可以再次使用
bool IsReusable { get; }
}
在ASP.NET WebForms中,System.Web.UI.Page和一般处理程序(.ashx)都继承了IHttpHandler接口,同样我们也可以自定义HttpHandler:
public class TestMyHandler : IHttpHandler
{
public bool IsReusable
{
get { return false; }
}
public void ProcessRequest(HttpContext context)
{
//... ...
}
}
这里注意同时还需要在Web.Config文件中配置一下:(注意IIS需为集成模式)
<system.webServer>
<handlers>
<add name="test" path="*.aaa" verb="*" type="TestMVC.TestMyHandler,TestMyHandler"/>
</handlers>
</system.webServer>
至此都是谈论的ASP.NET WebForms关于IHttpHandler的使用,在ASP.NET MVC中,定义了一个实现IHttpHandler接口的类型——MvcHandler,它会从路由对象RouteData中获取当前请求的Controller名称并根据上下文获取Controller工厂对象,再根据当前RequestContext对象,从Controller工厂创建具体的Controller对象,最后调用controller的Execute方法,执行我们控制器中的方法。
请看MvcHandler反编译的截图:

这里声明了一个IController和IControllerFactory对象,通过this.ProcessRequestInit()方法创建具体的Controller实例。

ProcessRequestInit方法用于获取controller实例与IControllerFactory对象
==============================================================
除了HttpHandler之外,Asp.net里面还有另外一个重要的角色——HttpModule,他的职责与HttpHandler类似,也是处理Http请求,只不过HttpModule是将某类HttpHandler都需要的相同功能(例如:请求拦截、身份认证、检查功能)抽取出来,做到重复利用。这里就不再详细叙述。