模塊是相當底層的,而且對每個來到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類兩方面做了一些對異步處理的改進,提供了更好的性能,但是在最終發布版本中這些是否會保留.