ASP.NET Framework深度歷險(3)
2024-07-10 12:58:32
供稿:網友
asp.net framework深度歷險(3)
author:uestc95
articletype:原創
e-mail:[email protected]
.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的生命周期圖,我只能暫且在這里用字符描繪一下前后流程了,如果你想要這個圖片,可以給我發送mail,我給你mail過去。
http request在整個httpmodule中的生命周期圖:
http request開始
|
httpmodule
|
httpmodule.beginrequest()
|
httpmodule.authenticaterequest()
|
httpmodule.authorizerequest()
|
httpmodule.resolverequestcache()
|
建立httphandler控制點
|
接著處理(httphandler已經建立,此后session可用)
|
httpmodule.acquirerequeststate()
|
httpmodule.prerequesthandlerexecute()
|
進入httphandler處理httprequest
|
httphandler.processrequest()
|
返回到httpmodule接著處理(httphandler生命周期結束,session失效)
|
httpmodule.postrequesthandlerexecute()
|
httpmodule.releaserequeststate()
|
httpmodule.updaterequestcache()
|
httpmodule.endrequest()
|
httpmodule.presendrequestheaders()
|
httpmodule.presendrequestcontent()
|
將處理后的數據返回客戶端
|
整個http request處理結束
怎么樣,從上面的圖中應當找到上次我們提出的第一個問題的答案了吧。
為了驗證上面的流程,我們可以用下面的這個自己的httpmoduel來驗證一下就知道了。
注意我們下面給出的是類的內容,框架還是前次我們給出的那個,自己加上就好了:
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()
{
}
好了,手累的不行了,:)
老規矩,下面的問題仔細考慮:
httpmodule中的application的多個事件和global.asax中的application事件有聯系嗎?如果有,該會有哪些聯系呢?
下回會探討httphandler的構建了,:)
不過最近挺忙,不知道何時能繼續......盡力吧。
see you later.
(待續,歡迎探討:[email protected])