直播中
這幾天胃口還算好,雖然算不上“吃嘛嘛香”,但是也算是不錯了,但愿能增上幾斤才好。
怎么樣,我們在Chapter Two最后提出的兩個問題估計早出來了吧,:)
First:為什么在HttpModule中不能使用Session?
Second:系統(tǒng)默認(rèn)的幾個HttpModule在哪里配置的?
我們先挑軟柿子捏,第二個問題的答案是:在文件machine.config中配置,比如在你的系統(tǒng)文件目錄中的C:\WI
NNT\Microsoft.NET\Framework\v1.0.3705\CONFIG\machine.config。
雖然是個軟柿子,但是還是有些東東在里面的,那就是machine.config和我們常見的web.config有什么關(guān)
系呢?在ASP.NET Framework啟動處理一個Http Request的時候,她會依次加載machine.config以及你請求頁面
所在目錄的web.config文件,里面的配置是有<remove>標(biāo)簽的,什么意思不說也知道了吧。如果你在machine.c
onfig中配置了一個自己的HttpModule,你仍然可以在離你最近web.config文件中“remove”掉這個映射關(guān)系。
至于第一個問題,呵呵,如果你仔細(xì)的運(yùn)行過上次的文件但是沒有自己仔細(xì)深入研究一下的話,一定會覺
得在HttpModule中的確無法使用Session,:)。如果你發(fā)現(xiàn)上次提出的問題本身就是一個"Problem",那么恭喜你,你沒有掉進(jìn)我故意給出的框框中,并且很有質(zhì)疑精神,:)
今天我們就來解釋一下HttpModule和HttpHandler之間的關(guān)系,在今天的“日記”完成的時候,你也就會發(fā)現(xiàn)第一個問題的答案了。
Chapter Three -- 深入HttpModule
我們曾經(jīng)提及當(dāng)一個Http Request被ASP.NET Framework捕獲之后會依次交給HttpModule以及HttpHandler來處理,但是不能理解為HttpModule和HttpHandler是完全獨立的,實際上是,在Http Request在HttpModule傳遞的過程中會在某個事件內(nèi)將控制權(quán)交給HttpHandler的,而真正的處理在HttpHandler中完成之后,再將控制權(quán)交還給HttpModule。也就是說HttpModule在某個請求經(jīng)過她的時候會再恰當(dāng)時候同HttpHandler進(jìn)行通信,在何時,如何通信呢?這就是下面提到的了。
我們提到在HttpModule中最開始的事件是BeginRequest,最終的事件是EndRequest。你如果仔細(xì)看上次給出的源程序的話,應(yīng)當(dāng)發(fā)現(xiàn)在方法Init()中參數(shù)我們傳遞的是一個HttpApplication類型,而我們曾經(jīng)提及的兩個事件正是這個傳遞進(jìn)來的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之后還會繼續(xù)執(zhí)行application.PreSendRequestHeaders以及application.PreSendRequestContent事件,而這兩個事件大家想必應(yīng)當(dāng)從名稱上面看得出來事做什么用途的了吧。是的,一旦觸發(fā)了這兩個事件,就表明整個Http Request的處理已經(jīng)完成了,在這兩個事件中是開始向客戶端傳送處理完成的數(shù)據(jù)流了。看到這里,您應(yīng)當(dāng)有一個疑問才對:怎么沒見到HttpHandler就處理完成了?不是提到過HttpHandler才是真正處理Http Request的嗎?如果你有這個疑問表明你是仔細(xì)在看,也不枉我打字打得這莫累,:)。
其實一開始我就提到了,在一個http request在HttpModule傳遞過程中,會在某一個時刻(確切的說應(yīng)當(dāng)是事件)中將這個請求傳遞給HttpHandler的。這個事件就是ResolveRequestCache,在這個事件之后,HttpModule會建立一個HttpHandler的入口實例(做好準(zhǔn)備了,:)),但是此時并沒有將控制權(quán)交出,而是繼續(xù)觸發(fā)AcquireRequestState以及PreRequestHandlerExecute事件(如果你實現(xiàn)了的話)??吹搅藛?,最后一個事件的前綴是Pre,呵呵。這表明下一步就要進(jìn)入HttpHandler了,的確如此,正如我們猜想的那樣,在PreRequestHandlerExecute事件之后,HttpModule就會將控制權(quán)暫時交給HttpHandler,以便進(jìn)行真正的http request處理工作。而在HttpHandler內(nèi)部會執(zhí)行ProcessRequest來處理請求。在HttpHandler處理完畢之后,會將控制權(quán)交還給HttpModule,HttpModule便會繼續(xù)對處理完畢的http Request進(jìn)行層層的轉(zhuǎn)交動作,直到返回到客戶端。
怎么樣,是不是有些混亂?呵呵,苦于純文本無法畫流程圖,我手頭上已經(jīng)畫好了一個整個HttpModule的生命周期圖,我只能暫且在這里用字符描繪一下前后流程了,如果你想要這個圖片,可以給我發(fā)送mail,我給你mail過去。
Http Request在整個HttpModule中的生命周期圖:
Http Request開始
|
HttpModule
|
HttpModule.BeginRequest()
|
HttpModule.AuthenticateRequest()
|
HttpModule.AuthorizeRequest()
|
HttpModule.ResolveRequestCache()
|
建立HttpHandler控制點
|
接著處理(HttpHandler已經(jīng)建立,此后Session可用)
|
HttpModule.AcquireRequestState()
|
HttpModule.PreRequestHandlerExecute()
|
進(jìn)入HttpHandler處理HttpRequest
|
HttpHandler.ProcessRequest()
|
返回到HttpModule接著處理(HttpHandler生命周期結(jié)束,Session失效)
|
HttpModule.PostRequestHandlerExecute()
|
HttpModule.ReleaseRequestState()
|
HttpModule.UpdateRequestCache()
|
HttpModule.EndRequest()
|
HttpModule.PreSendRequestHeaders()
|
HttpModule.PreSendRequestContent()
|
將處理后的數(shù)據(jù)返回客戶端
|
整個Http Request處理結(jié)束
怎么樣,從上面的圖中應(yīng)當(dāng)找到上次我們提出的第一個問題的答案了吧。
為了驗證上面的流程,我們可以用下面的這個自己的HttpModuel來驗證一下就知道了。
注意我們下面給出的是類的內(nèi)容,框架還是前次我們給出的那個,自己加上就好了:
public void Init(HttpApplication application)
{
application.BeginRequest += (new EventHandler(this.Application_BeginRequest));
application.EndRequest += (new EventHandler(this.Application_EndRequest));
application.PreRequestHandlerExecute +=(new EventHandler(this.Application_PreRequestHandlerExecute));
application.PostRequestHandlerExecute +=(new EventHandler(this.Application_PostRequestHandlerExecute));
application.ReleaseRequestState +=(new EventHandler(this.Application_ReleaseRequestState));
application.AcquireRequestState +=(new EventHandler(this.Application_AcquireRequestState));
application.AuthenticateRequest +=(new EventHandler(this.Application_AuthenticateRequest));
application.AuthorizeRequest +=(new EventHandler(this.Application_AuthorizeRequest));
application.ResolveRequestCache +=(new EventHandler(this.Application_ResolveRequestCache));
application.PreSendRequestHeaders +=(new EventHandler(this.Application_PreSendRequestHeaders));
application.PreSendRequestContent +=(new EventHandler(this.Application_PreSendRequestContent));
}
private void Application_PreRequestHandlerExecute(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
context.Response.Write("Application_PreRequestHandlerExecute<br>");
}
private void Application_BeginRequest(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
context.Response.Write("Application_BeginRequest<br>");
}
private void Application_EndRequest(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
context.Response.Write("Application_EndRequest<br>");
}
private void Application_PostRequestHandlerExecute(Object source,EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
context.Response.Write("Application_PostRequestHandlerExecute<br>");
}
private void Application_ReleaseRequestState(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
context.Response.Write("Application_ReleaseRequestState<br>");
}
private void Application_UpdateRequestCache(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
context.Response.Write("Application_UpdateRequestCache<br>");
}
private void Application_AuthenticateRequest(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
context.Response.Write("Application_AuthenticateRequest<br>");
}
private void Application_AuthorizeRequest(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
context.Response.Write("Application_AuthorizeRequest<br>");
}
private void Application_ResolveRequestCache(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
context.Response.Write("Application_ResolveRequestCache<br>");
}
private void Application_AcquireRequestState(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
context.Response.Write("Application_AcquireRequestState<br>");
}
private void Application_PreSendRequestHeaders(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
context.Response.Write("Application_PreSendRequestHeaders<br>");
}
private void Application_PreSendRequestContent(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
context.Response.Write("Application_PreSendRequestContent<br>");
}
public void Dispose()
{
}
好了,手累的不行了,:)
老規(guī)矩,下面的問題仔細(xì)考慮:
HttpModule中的Application的多個事件和Global.asax中的Application事件有聯(lián)系嗎?如果有,該會有哪些聯(lián)系呢?
下回會探討HttpHandler的構(gòu)建了,:)
不過最近挺忙,不知道何時能繼續(xù)......盡力吧。
See you later.
(待續(xù),歡迎探討:uestc95@263.net)