原文地址:http://www.cnblogs.com/skm-blog/p/3188697.html
如果您看了我的前四篇文章,应该知道目前Http请求已经流到了HttpModule这个程序员手中了,而且我们可以注册自己的HttpModule并且可以在里面注册一些事件来控制这个Http请求,但是到目前为止我们还没有真正的处理这个Http请求,那究竟什么时候开始处理呢,又是怎样处理的呢,下面我们来简单探讨一下!
其实是在HttpModule中触发PreRequestHandlerExecute事件之后,才真正把控制权交给了HttpHandler这个程序员,在第一篇中我们说到,HttpHandler它他天生就会处理页面,它用了一招“乾坤大挪移”的功夫,就把上下文Context中的Request对象给处理了(就是处理了Http请求),并且把最终生成的Html填充的Context中的Response对象中,然后就又一步一步传给了IIS,IIS又给了请求者。
那么:
1、 所谓的“乾坤大挪移”到底是个什么功夫呢
2、 P_Handler又是如何被调用如何消亡的呢?
3、 我们自己是否也可以创建HttpHandler呢?
4 、 HttpHandler和我们常用的.ashx又是什么关系呢?
从字面上我们也可以看出,HttpHandler就是handle http(request)的,就像程序员,就是(做)程序的人员一样,所以P_Handler就是个典型的HttpRequest处理人员。我们也知道IHttpHandler接口,它就像是一个认证,任何通过了IHttpHandler认证(实现了这个接口)的人员(handler),都可以处理HttpRequest。这个认证主要有两个内容(方法):1,ProcessRequest;2,IsReusable。
asp.net中有很多默认的HttpHandler,当然每种类型的文件对应了不同的Handler去处理,我们可以从C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config这个路径下找到一个叫做web.config的文件,打开如下:
<add path="*.config" verb="*" type="System.Web.HttpForbiddenHandler" validate="true" />我们可以知道我们项目中的web.config文件为什么不能访问了,原来是被 HttpForbiddenHandler给屏蔽了,我估计它是直接返回了一个错误,这样我们就不能访问这些资源,同样的,.sitemap, .asax, ..cs, .csproj等等我们熟悉的项目中的文件都是使用HttpForbiddenHandler来屏蔽掉的。
拿<add path="*.aspx" verb="*" type="System.Web.UI.PageHandlerFactory" validate="True" />做例子,给大家稍微解释一下:
path就是说所请求的文件的类型 verb代表请求的方式 如Get,Post,*代表全部;type代表由System.Web.UI命名空间下的PageHandlerFactory这个类去处理。Validate=True代表允许的意思。(如有错误,还请留言)
那么我们可以看到,我们最最常访问的页面.aspx原来是交由PagehandlerFactory类处理的,那么PageHandlerFactory又是什么呢,反编译一下可以看到如下:
我们可以看到这个类没有继承IHttpHandler这个接口,那么我们前面不是说所有处理Http请求的类都必须实现IHttpHandler这个接口吗?这是怎么回事呢,接着看,我们发现原理这个PageHandlerFactory类有两个很特别的方法,一个是GetHandler,一个是GetHandlerHelper,反编译看一下,我们发现GetHandler方法内部直接调用GetHandlerHelper方法,就不贴出来了,那么我们看一下GetHandlerHelper内部是什么样的?如下
看到这里我想你是不是很熟悉了啊,它原来返回一个Page类,怪不得我们每次建立一个.aspx页面都会默认继承自Page类呢,再看看Page类的定义如下
public class Page : TemplateControl, IHttpHandler{}
我们更加的确信,原来一个.aspx请求过来都是由Page类去处理的啊。也就是说page类就是专门处理.aspx页面请求的一个Httphandler。那么下面我们还有几个问题没有解决: 第一:怎么定义自己的HttpHandler。 第二:HttpHandler中的PR方法到底怎么样执行的,有哪些事件,顺序如何。 听我慢慢道来: 要定义我们自己的HttpHandler其实也很容易 首先:创建一个类,实现IHttpHandler接口,我写的代码如下
namespace ClassLibrary2{ public class MyHttpHandler:IHttpHandler { public bool IsReusable { get { throw new NotImplementedException(); } } public void ProcessRequest(HttpContext context) { HttpResponse response = context.Response; response.Write("这是自定义的HttpHandler"); } }}
然后:在web.config文件中配置一下我们的MyHttpHandler是处理哪种类型的文件(本实例一.song格式的文件为例,宋是本人的姓),代码如下:
最后:在web服务器也就是IIS上配置一下,有些人不明白为什么,其实道理很简单,当我们请求Default.song这个文件时,IIS看到.song就不知道交给谁处理了,所以我们在IIS上配置就是为了告诉IIS还交给aspnet_isapi.dll文件处理,还走正常的.aspx页面请求的管道,不同的是经过HttpModule之后,这个请求不在交给page类处理了,而是转交给了我们自己定义的MyHttpHandler去处理了。配置如下:
本人用的IIS7.0步骤如下:
第一:找到处理程序映射选项,如图
第二:双击处理程序映射,在右侧点击添加脚本映射,如图
第三:还是在右侧点击添加管理处理程序,如图
这样我们在浏览器中请求Default.song(这个文件不存在),IIS看到后缀名是.song的文件就会交给aspnet_isapi.dll文件处理,流过HttpModule之后就会交给我们自己定义的MyHttpHandler处理,结果如下:
看到这里您应该对HttpHandler有一个整体的了解了,但是他内部的PR方法究竟怎么样执行的,执行了哪些事件,顺序又是怎么样的呢,我们还不清楚,这篇文章写的有点长了,怕有些人没有耐性看,所以我打算放到下一篇和大家探讨,请继续关注。
本系列:
一:
二:
三:
四: