Asp.net大檔案上傳(二)
吳劍 2009-04-20
轉載請註明出處:http://www.cnblogs.com/wu-jian/
3. Asp.net管道
3.1 主要流程
從請求進入ASP.NET工作者進程,直至它到達最終的處理常式之前要經過一系列的步驟和過程,這個步驟和過程本文中將其稱之為ASP.NET管道,關於ASP.NET管道我並未找到相關官方的標準文檔,而是根據Fritz Onion的《ASP.NET基礎教程》整理而來。
1、ASP.NET管道的第一步是建立HttpWorkerRequest對象,它包含與當前請求有關的所有資訊,包括請求的URL、標題等等。
2、把請求傳遞給HttpRuntime類的靜態ProcessRequest方法。
3、HttpRutime類執行的第一件事情是建立HttpContext對象,並用HttpWorkerRequest類進行初始化。HttpContext類是管道的“粘合劑”,因為它把與當前請求有關的所有資訊儲存在一個地方,把所有類合成一體。第一次建立HttpContext對象時,它分配HttpRequest和HttpResponse類的新執行個體並且欄位儲存它們。它還為應用程式和工作階段狀態提供了專用的訪問器。(關於HttpContext請參閱3.2節)
4、一旦創建立了HttpContext類,HttpRuntime類就通過調用HttpApplicationFactory類的靜態GetApplicationInstance方法,為該應用程式請求HttpApplication衍生類別的一個執行個體。
5、GetApplicationInstance要麼建立HttpApplication(或衍生類別)類的一個新執行個體,要麼從應用程式物件池中拖出一個執行個體。(關於HttpApplication請參閱3.3節)
6、一旦建立或檢索到HttpApplication類,就對它進行初始化,並在初始化期間分配為此應用程式定義的所有模組。模組是實現IHttpModule介面的類,它為進程前後的請求提供服務。
7、一旦建立了模組,HttpRuntime類通過調用它的BeginProcessRequest方法,要求最新檢索到的HttpApplication類對當前請求提供服務。然後,為當前請求找到合適的處理常式工廠。
8、建立處理常式,傳遞當前HttpContext,一旦ProcessRequest方法返回,請求完成。
3.2. HttpContext
上下文(HttpContextAsp.net)是Asp.net管道中最重要的一個類,該類維護所有與請求有關的資料,並且可以為管道中的大多數元素所訪問,在請求的生命週期裡,上下文一直是有效。並且可以通過靜態HttpContext.Current屬性訪問,正如它的名字暗示的那樣,HttpContext對象表示當前活動請求的上下文,因為它包含了在請求生命週期裡你會用到的所有必需對象的引用,如:Request,Response,Application,Server,Cache。在請求處理過程的任何時候,你都可以使用HttpContext.Current訪問這些對象。記住HttpContext是你的朋友,在請求或者頁面處理的不同階段,如果你需要相關資料都可以使用它擷取。
3.3. HttpApplication
HttpApplication主要用作是Asp.net管道的事件控制器,負責請求的傳輸,通過觸發事件,通知應用程式正在發生的事情。HttpApplication本身並不知曉發送給Web程式的資料,它僅僅是個訊息郵遞者,只負責事件之間的通訊。它觸發事件,然後通過傳遞HttpContext對象,把資訊發送給被調用的方法。Asp.net管道的事件按照順序逐一觸發事件,如所示:
HttpApplication向外界提供的事件
事件 |
啟用原因 |
順序 |
BeginRequest |
收到新的請求 |
1 |
AuthenticateRequest |
已經確立使用者的安全身份 |
2 |
AuthorizeRequest |
已經驗證使用者授權 |
3 |
ResolveRequestCache |
在受權以後但是在調用處理常式之前,如果找到緩衝入口,則被緩衝模組用來繞過處理常式的執行。 |
4 |
AcquireRequestState |
載入工作階段狀態 |
5 |
PreRequestHandlerExecute |
請求發送到處理常式之前 |
6 |
PostRequestHandlerExecute |
請求發送到處理常式之後 |
7 |
ReleaseRequestState |
所有請求處理常式完成以後,被狀態模組用來儲存狀態資料 |
8 |
UpdateRequestCache |
處理常式執行以後,被緩衝模組用來儲存緩衝中的響應 |
9 |
EndRequest |
請求被處理以後 |
10 |
Disposed |
正好在關閉應用程式之前 |
|
Error |
出現一個未經處理過的應用程式錯誤時 |
|
PreSendRequestContent |
內容發送到客戶之前 |
|
PreSendRequestHeaders |
HTTP標題發送到客戶之前 |
|
3.4. IHttpModule
模組(HttpModule)是功能最強大的擴充點,它們在第一次建立應用程式時被建立,並且在應用程式的生命期內一直存在,可以接進任何一個HttpApplication事件。通常用於執行請求的預先處理和後加工,在許多方面類似於IIS中的ISAPI過濾器。ASP.NET本身就用模組實現了許多應用程式級功能,包括身分識別驗證、授權、緩衝、及進程外工作階段狀態管理。
如下樣本了一個HttpModule的實現:
C#
using System;
using System.Web;
namespace Test
{
publicclass MyModule : IHttpModule
{
publicvoid Dispose(){}
publicvoid Init(HttpApplication app)
{
app.BeginRequest +=new EventHandler(this.Application_BeginRequest);
app.EndRequest +=new EventHandler(this.Application_EndRequest);
}
protectedvoid Application_BeginRequest(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
app.Context.Response.Write("This Is MyModule Application_BeginRequest .");
}
protectedvoid Application_EndRequest(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
app.Context.Response.Write("This Is MyModule Application_EndRequest .");
}
}
}
web.config
<httpModules>
<add name="myModule" type="Test.MyModule, Test"/>
</httpModules>
3.5. IHttpHandler
C#
using System;
using System.Web;
namespace Test
{
publicclass MyHandler : IHttpHandler
{
publicvoid ProcessRequest(HttpContext cont)
{
cont.Response.Write("This Is MyHandler ."+"<br />");
}
publicbool IsReusable {
get { returntrue; }
}
}
}
web.config
<httpHandlers>
<add verb="GET" path="*.aspx" type="Test.MyHandler, Test"/>
</httpHandlers>
從如上代碼可以發現,實現一個HttpHandler看似非常簡單,它僅僅包含一個ProcessRequest()方法和一個IsReusable屬性。但真是如此簡單嗎?記住,WebForms和WebServices都是作為HttpHandler實現的,在這個看似簡單的介面裡,其實很多的實現過程被隱藏了,我們只是做了簡單輸出而以。但關鍵點是通過ProcessRequest()可以得到一個HttpContext對象的執行個體,並且明白這個單獨的方法可以從開始到結束負責處理一個Web請求。
另外大家可能注意到了IHttpHandler介面支援一個名稱為IsReusable的唯讀屬性,用於指明是否可以安全的共用一個特定處理常式的執行個體。如果構建一個自訂處理常式,並且從此屬性返回true,則在用處理常式的執行個體對請求提供服務時,Asp.net共用處理常式的執行個體。如果返回false,則每次服務要求時要建立處理常式的一個新執行個體。通常,處理常式共用與否並沒有多大差別,因為CLR中的執行個體化機制和記憶體回收行程是非常有效,所以共用處理常式類並不會得到多大好處。需要考慮使用共用的一種情況是,需要耗費大量時間的處理常式,比如從資料庫中進行檢索。而Asp.net提供的標準處理常式從不使用處理常式共用。
上一篇:Asp.net大檔案上傳(一) | 下一篇:未完待續