asp.net|架構
模組是相當底層的,而且對每個來到ASP.NET應用程式的請求都會被觸發.Http處理器更加的專註並處理映射到這個處理器上的請求.
Http處理器需要實現的東西非常簡單,但是通過訪問HttpContext對象它可以變得非常強大.Http處理器通過實現一個非常簡單的IHttpHandler介面(或是它的非同步版本,IHttpAsyncHandler),這個介面甚至只含有一個方法-ProcessRequest()-和一個屬性IsReusable.關鍵區段是ProcessRequest(),這個函數擷取一個HttpContext對象的執行個體作為參數.這個函數負責從頭到尾處理Web請求.
單獨的,簡單的函數?太簡單了,對吧?好的,簡單的介面,但並不弱小!記住WebForm和WebService都是作為Http處理器實現的,所以在這個看上去簡單的介面中封裝了很強大的能力.關鍵是這樣一個事實,當一個請求來到Http處理器時,所有的ASP.NET的內部對象都被準備和設定好來處理請求了.主要的是HttpContext對象,提供所有相關的請求功能來接收輸入並輸出回Web伺服器.
對一個HTTP處理其來說所有的動作都在這個單獨的ProcessRequest()函數的調用中發生.這像下面所展示的這樣簡單:
public void ProcessRequest(HttpContext context)
{
context.Response.Write("Hello World");
}
也可以像一個可以從HTML模板渲染出複雜表單的WebForm頁面引擎那麼完整,複雜.通過這個簡單,但是強大的介面要做什麼,完全取決於你的決定.
因為Context對象對你是可用的,你可用訪問Request,Response,Session和Cache對象,所以你擁有所有ASP.NET請求的關鍵特性,可以獲得使用者提交的內容並返回你產生的內容給用戶端.記住HttpContext對象-它是你在整個ASP.NET請求的生命週期中的”朋友”.
處理器的關鍵操作應該是將輸出寫入Response對象或者更具體一點,是Response對象的OutputStream.這個輸出是實際上被送回到用戶端的.在幕後,ISAPIWorkerRequest管理著將輸出資料流返回到ISAPI ecb的過程.WriteClient方法是實際產生IIS輸出的方法.
圖7-ASP.NET請求管道通過一系列事件介面來轉寄請求,提供了更大的靈活性.Application當請求到來並通過管道時作為一個載入Web應用並觸發事件的宿主容器.每個請求都沿著配置的Http過濾器和模組的路徑走(譯註:原文為Http Filters And Modules,應該是指Http Module和Http Handler).過濾器可以檢查每個通過管道的請求,Handler允許實現應用程式邏輯或者像Web Form和WebService這樣的應用程式層介面.為了嚮應用提供輸入輸出,Context對象在這個處理過程中提供了特定於請求的的資訊.
WebForm使用一系列在架構中非常高層的介面來實現一個Http處理器,但是實際上WebForm的Render()方法簡單的以使用一個HtmlTextWriter對象將它的最終結果輸出到context.Response.OutputStream告終.所以非常夢幻的,終究即使是向WebForm這樣進階的工具也只是在Request和Response對象之上進行了抽象而已.
到了這裡你可能會疑惑在Http handler中你到底需要處理什麼.既然WebForm提供了簡單可用的Http Handler實現,那麼為什麼需要考慮更底層的東西而放棄這擴充性呢?
WebForm對於產生複雜的HTML頁面來說是非常強大的,業務層邏輯需要圖形布局工具和基於模組的頁面.但是WebForm引擎做了一系列overhead intensive的任務.如果你想要做的是從系統中讀入一個檔案並通過代碼將其返回的話,不通過WebForm架構直接返迴文件會更有效率.如果你要做的是類似從資料庫中讀出圖片的工作,並不需要使用頁面架構-你不需要模板而且確定不需要Web頁面並從中捕捉使用者事件.
沒有理由需要建立一個頁面對象和Session並捕捉頁面層級的事件-所有這些需要執行對你的任務沒有協助的額外的代碼.
所以自訂處理器更加有效率.處理器也可用來做WebForm做不到的事情,例如不需要在硬碟上有物理檔案就可用處理請求的能力,也被稱為虛擬Url.要做到這個,確認你在圖1中展示的應用擴充對話方塊中關掉了”檢查檔案存在”選項.
這對於內容供應商來說非常常見,象動態圖片處理,XML服務,URL重新導向服務提供了vanity Urls,下載管理以及其他,這些都不需要WebForm引擎.
非同步HTTP Handler
在這篇文章中我大部分都在討論同步處理,但是ASP.NET運行時也可以通過非同步HTTP handler來支援非同步作業.這些處理器自動的將處理”卸載”到獨立的線程池的線程中並釋放主ASP.NET線程,使ASP.NET線程可以處理其他的請求.不幸的是在1.x版的.NET中,”卸載”後的處理還是在同一個線程池中,所以這個特性之增加了一點點的效能.為了建立真正的非同步行為,你必須建立你自己的線程並在回調處理中自己管理他們.
目前的版本的ASP.NET 2.0 Beta 2在IhttpHandlerAsync(譯註:此處應該是指IHttpAsyncHandler,疑為作者筆誤)介面和Page類兩方面做了一些對非同步處理的改進,提供了更好的效能,但是在最終發布版本中這些是否會保留