一,什么是HttpHandler
在asp.net的网站中,在一个普通的请求地址“http://localhost:56093/Default.aspx”中“Default.aspx”就是handler。
也就是说在asp.net中page就是handler,在asp.net MVC中Controller就是handler,handler就是最终处理请求的那个类。
假如http://localhost:56093/Default.aspx这个页面输出的是"Helloworld"几个字。现在http://localhost:56093/这个站点下有100个页面,我想要这个站点的请求都输出
Helloworld字眼怎么办,并且我要所有的请求都必须验证登录了。那是不是需要在100个页面上都写代码呢。微软这么厉害肯定给出了简单的解决方案。就是“HttpModule”.
二,简单的请求流程
相信各位看了不少asp.net请求处理流程的文档。这里推荐园子里Edison Chou的ASP.Net请求处理机制初步探索之旅。
在请求进入到ASP.NET管道后,有三个重要的类,“ISAPIRuntme”,“HttpRuntime”,"HttpApplication".
1,ISAPIRuntme中根据报文创建了“HttpWorkerRequest”类。
2,接着HttpRuntime开始干活,而且大部分的活都是HttpRuntime在干。HttpRuntime初始化了HttpWorkerRequest创建了HttpContent,创建了HttpRequest和HttpResponse,3,创建了HttpApplication(web应用程序实例)。最后调用handler处理请求的也是HttpRuntime中完成的。
3,HttpApplication中初始化各个HttpModule并且注册HttpApplication的19个事件(并且所有的HttpModule都注册了19事件,只是HttpApplication有19事件可以去让HttpModule注册,注册了就会被执行)。
然后HttpRuntime会依次去执行各个HttpModule的相应的事件。接着去调用匹配的handler,然后以回到HttpModule相应的事件,然后一层层返回,直到IIS把内容返回给浏览器。
三,什么HttpModule
IHttpModule就是一个接口,有个重要的方法“void Init(HttpApplication context)”,在这个方法里可以给context(HttpApplication )注册事件。
任何类继承了IHttpModule并且在config中配置了,那么在HttpApplication 的管道中,它的事件就会被执行(如果注册了的话)。
asp.net默认的HttpModule有:
asp.net中有身份验证功能,如果表单验证,如果没登录就会在处理请求之前跳转到登录页面。就是在“FormsAuthentication”中完成的。
这些HttpModule,在HttpApplication中全部会加载进来,在HttpRuntime中会依次去执行它的19个事件(全部19个事件全部注册了的话)
1,那什么时候去执行handler呢
在第11个事件“PreRequestHandlerExecute”和第12个事件“PostRequestHandlerExecute“之间去调用handler,调用完后继续执行httpmodule剩下的事件。
2,这么多HttpModule,HttpRuntime是怎么去执行的呢?
按HttpModule的顺序依次执行,假如有两个HttpModule:Module1和Module2,那么第一个事件”BeginRequest“的执行顺序是:Module1的BeginRequest,Module2的BeginRequest。
3,是不是每个HttpModule里都会执行一次Handler呢?
不是,handler只执行一次。在所有HttpModule的前面11个事件依次执行完后去调用handler,调用完后再依次执行HttpModule剩下的事件。
例子如下:
第一个HttpModule:
第二个HttpModule:
handler处理:
配置HttpModule,让HttpAplication加载:
请求这个Default页面显示的效果为:
四,为什么要有HttpModule
有许多功能是需要我们在handler之前就要去做的,而且也不可能去每一个handler去做,比如身份验证。
在实际业务场景中我们也有可能需要在handler之前做大量的工作。所以微软就公开了这个接口,可以让我们更灵活的应用在我们的业务场景中。
五,ASP.NET MVC的区别
asp.net mvc与asp.net的请求管道模型是一样的。mvc最重要的是它的路由功能,而且它的本质上就是一个HttpModule,
在asp.net全局配置文件中配置了这个Module,UrlRoutingModule源码
在该Module中注册了”PostResolveRequestCache“事件,对请求进行拦截。根据mvc的路由规则找到对应的controller(handler),然后调用匹配的action.