日期:2013-09-09  浏览次数:20423 次

ASP.NET Framework深度历险(3)

Author:uestc95
ArticleType:原创
E-mail:uestc95@263.net
.NET Framework Version:1.0.3705正式版
VS.NET(C#) Version:7.0.9466正式版



    这几天胃口还算好,虽然算不上“吃嘛嘛香”,但是也算是不错了,但愿能增上几斤才好。
    怎么样,我们在Chapter Two最后提出的两个问题估计早出来了吧,:)
    First:为什么在HttpModule中不能使用Session?
    Second:系统默认的几个HttpModule在哪里配置的?

    我们先挑软柿子捏,第二个问题的答案是:在文件machine.config中配置,比如在你的系统文件目录中的C:\WI

NNT\Microsoft.NET\Framework\v1.0.3705\CONFIG\machine.config。
    虽然是个软柿子,但是还是有些东东在里面的,那就是machine.config和我们常见的web.config有什么关

系呢?在ASP.NET Framework启动处理一个Http Request的时候,她会依次加载machine.config以及你请求页面

所在目录的web.config文件,里面的配置是有<remove>标签的,什么意思不说也知道了吧。如果你在machine.c

onfig中配置了一个自己的HttpModule,你仍然可以在离你最近web.config文件中“remove”掉这个映射关系。
    至于第一个问题,呵呵,如果你仔细的运行过上次的文件但是没有自己仔细深入研究一下的话,一定会觉

得在HttpModule中的确无法使用Session,:)。如果你发现上次提出的问题本身就是一个"Problem",那么恭喜你,你没有掉进我故意给出的框框中,并且很有质疑精神,:)
    今天我们就来解释一下HttpModule和HttpHandler之间的关系,在今天的“日记”完成的时候,你也就会发现第一个问题的答案了。

    Chapter Three -- 深入HttpModule

    我们曾经提及当一个Http Request被ASP.NET Framework捕获之后会依次交给HttpModule以及HttpHandler来处理,但是不能理解为HttpModule和HttpHandler是完全独立的,实际上是,在Http Request在HttpModule传递的过程中会在某个事件内将控制权交给HttpHandler的,而真正的处理在HttpHandler中完成之后,再将控制权交还给HttpModule。也就是说HttpModule在某个请求经过她的时候会再恰当时候同HttpHandler进行通信,在何时,如何通信呢?这就是下面提到的了。
    我们提到在HttpModule中最开始的事件是BeginRequest,最终的事件是EndRequest。你如果仔细看上次给出的源程序的话,应当发现在方法Init()中参数我们传递的是一个HttpApplication类型,而我们曾经提及的两个事件正是这个传递进来的HttpApplication的事件之一。
    HttpApplication还有其它的事件,分别如下:
            application.BeginRequest
            application.EndRequest
            application.PreRequestHandlerExecute
            application.PostRequestHandlerExecute
            application.ReleaseRequestState
            application.AcquireRequestState
            application.AuthenticateRequest
            application.AuthorizeRequest
            application.ResolveRequestCache
            application.PreSendRequestHeaders
            application.PreSendRequestContent

      需要注意的是,在事件EndRequest之后还会继续执行application.PreSendRequestHeaders以及application.PreSendRequestContent事件,而这两个事件大家想必应当从名称上面看得出来事做什么用途的了吧。是的,一旦触发了这两个事件,就表明整个Http Request的处理已经完成了,在这两个事件中是开始向客户端传送处理完成的数据流了。看到这里,您应当有一个疑问才对:怎么没见到HttpHandler就处理完成了?不是提到过HttpHandler才是真正处理Http Request的吗?如果你有这个疑问表明你是仔细在看,也不枉我打字打得这莫累,:)。
    其实一开始我就提到了,在一个http request在HttpModule传递过程中,会在某一个时刻(确切的说应当是事件)中将这个请求传递给HttpHandler的。这个事件就是ResolveRequestCache,在这个事件之后,HttpModule会建立一个HttpHandler的入口实例(做好准备了,:)),但是此时并没有将控制权交出,而是继续触发AcquireRequestState以及PreRequestHandlerExecute事件(如果你实现了的话)。看到了吗,最后一个事件的前缀是Pre,呵呵。这表明下一步就要进入HttpHandler了,的确如此,正如我们猜想的那样,在PreRequestHandlerExecute事件之后,HttpModule就会将控制权暂时交给HttpHandler,以便进行真正的http request处理工作。而在HttpHandler内部会执行ProcessRequest来处理请求。在HttpHandler处理完毕之后,会将控制权交还给HttpModule,HttpModule便会继续对处理完毕的http Request进行层层的转交动作,直到返回到客户端。
   怎么样,是不是有些混乱?呵呵,苦于纯文本无法画流程图,我手头上已经画好了一个整个HttpModule的生命周期图,我只能暂且在