熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

ASP.NET中的HTTP模塊和處理程序(上)

2013-11-13 09:49:10  來源: .NET編程 

  介紹 
   
  在Internet時代的開端客戶端的需求非常有限文件就可以滿足他們的需求但是隨著時間的流逝客戶端需求的擴充超越文件或靜態文件所包含的功能 
   
  開發者需要擴充或擴展Web服務器的功能Web服務器廠商設計了不同的解決方案但是都遵循同一個主題向Web服務器插入某些組件所有的Web服務器補充技術都允許開發者建立並插入組件以增強Web服務器的功能微軟公司提出了ISAPI(Internet服務器API)網景公司提出了NSAPI(網景服務器API)等等 
   
  ISAPI是一種重要的技術它允許我們增強與ISAPI兼容的Web服務器(IIS就是一種與ISAPI兼容的Web服務器)的能力我們使用下面的組件達到這個目的
  
    · ISAPI擴展
  
    · ISAPI過濾器 
   
  ISAPI擴展是使用Win動態鏈接庫來實現的你可以把ISAPI擴展看作是一個普通的應用程序ISAPI擴展的處理目標是http請求這意味著你必須調用它們才能激活它們 你可以認為ISAPI過濾器僅僅就是一個過濾器而已客戶端每次向服務器發出請求的時候請求要經過過濾器客戶端不需要在請求中指定過濾器只需要簡單地把請求發送給Web服務器接著Web服務器把請求傳遞給相關的過濾器接下來過濾器可能修改請求執行某些登錄操作等等 
   
  由於這些組件的復雜性實現它們非常困難開發者不得不使用C/C++來開發這些組件但是對於很多人來說使用C/C++進行開發簡直就是痛苦的代名詞 
   
  那麼ASPNET提供什麼東西來實現這些功能呢?ASPNET提供的是HttpHandler(HTTP處理程序)和HttpModule(HTTP模塊) 
   
  在深入了解這些組件的詳細信息之前了解一下http請求經過HTTP模塊和HTTP處理程序的時候的處理流程是有價值的
  
    建立示例應用程序
  
    我建立了下面一些的C#項目以演示應用程序的不同組件
  
    · NewHandler (HTTP處理程序)
  
    · Webapp (演示HTTP處理程序)
  
    · SecurityModules (HTTP模塊)
  
    · Webapp (演示HTTP模塊)
  
   這些應用程序的安裝步驟
  
    · 解開attached zip文件中的所以代碼
  
    · 建立兩個虛擬目錄webapp和webapp把這兩個目錄指向Webapp和Webapp應用程序的實際物理目錄
  
    · 把NewHandler項目中的Newhandlerdll文件復制到webapp應用程序的bin目錄
  
    · 把SecurityModules項目中的SecurityModulesdll文件復制到webapp應用程序的bin目錄中

  ASPNET請求的處理過程 
   
  ASPNET請求處理過程是基於管道模型的在模型中ASPNET把http請求傳遞給管道中的所有模塊每個模塊都接收http請求並有完全控制權限模塊可以用任何自認為適合的方式來處理請求一旦請求經過了所有HTTP模塊就最終被HTTP處理程序處理HTTP處理程序對請求進行一些處理並且結果將再次經過管道中的HTTP模塊
  


  請注意在http請求的處理過程中只能調用一個HTTP處理程序然而可以調用多個HTTP模塊 
  
  Http處理程序 
   
  HTTP處理程序是實現了SystemWebIHttpHandler接口的NET組件任何實現了IHttpHandler接口的類都可以用於處理輸入的HTTP請求HTTP處理程序與ISAPI擴展有些類似HTTP處理程序和ISAPI擴展的差別在於在URL中可以使用HTTP處理程序的文件名稱直接調用它們與ISAPI擴展類似 
   
  HTTP處理程序實現了下列方法 
   
  方法名稱描述ProcessRequest 這個方法實際上是http處理程序的核心我們調用這個方法來處理http請求IsReusable 我們調用這個屬性來決定http處理程序的實例是否可以用於處理相同其它類型的請求HTTP處理程序可以返回true或false來表明它們是否可以重復使用 
   
  你可以使用nfig或者nfig文件把這些類映射到http請求上映射完成以後當接收到相應請求的時候ASPNET會實例化http處理程序我們將解釋如何在nfig和/或nfig文件中定義所有這些細節信息 
   
  ASPNET還通過IHttpHandlerFactory接口支持http處理程序的擴展ASPNET提供了把http請求路由到實現IHttpHandlerFactory接口的類的對象上的能力此外ASPNET還利用了Factory設計模式這種模式為建立一組相關對象而不提供具體類的功能提供了接口簡單的說你可以把用於建立依賴傳遞進來的參數建立的http處理程序對象的類看作是factory(工廠)我們不用指定需要實例化的特定的http處理程序http處理程序工廠處理這種事務這樣做的優點在於如果未來實現IHttpHandler接口的對象的實現方法發生了改變只要接口仍然相同客戶端就不會受到影響
  
    下面是IHttpHandlerFactory接口中的方法列表 
   
  方法名稱描述GetHandler 這個方法負責建立適當的處理程序並把它的指針返回到調用代碼(ASPNET運行時)這個方法返回的處理程序對象應該實現了IHttpHandler接口ReleaseHandler 這個方法負責在請求處理完成後釋放http處理程序Factory 實現決定了它的操作Factory 實現可以是實際摧毀實例也可以把它放入緩沖池供以後使用
  
    在配置文件中注冊HTTP處理程序和HTTP處理程序工廠
  
    ASPNET在下面的配置文件中維護自己的配置信息
  
    · nfig
  
    · nfig
  
    nfig文件包含應用於計算機上安裝的所有Web應用程序的配置設置信息 
   
  nfig文件對於每個Web應用程序來說是特定的每個Web應用程序都有自己的nfig文件Web應用程序的任何子目錄也可能包含自己的nfig文件這使得它們能夠覆蓋父目錄的設置信息 

  為了給我們的Web應用程序添加HTTP處理程序你可以使用<httpHandlers>和<add>節點實際上處理程序都帶有<add>節點列舉在<httpHandlers>和</httpHandlers>節點之間下面是添加HTTP處理程序的一個普通的例子
  
  <httpHandlers>
   <add verb=supported http verbs path=path type=namespaceclassname assemblyname />
  <httpHandlers>
  
    在上面的XML中 
   
  · Verb屬性指定了處理程序支持的HTTP動作如果某個處理程序支持所有的HTTP動作請使用*否則使用逗號分隔的列表列出支持的動作因此如果你的處理程序只支持HTTP GET和POST那麼verb屬性就應該是GET POST 
   
  · Path屬性指定了需要調用處理程序的路徑和文件名(可以包含通配符)例如如果你希望自己的處理程序只有在testxyz文件被請求的時候才被調用那麼path屬性就包含testxyz如果你希望含有xyz後綴的所有文件都調用處理程序path屬性應該包含*xyz 
   
  · Type屬性用名字空間類名稱和部件名稱的組合形式指定處理程序或處理程序工廠的實際類型ASPNET運行時首先搜索應用程序的bin目錄中的部件DLL接著在全局部件緩沖(GAC)中搜索

  ASPNET運行時對HTTP處理程序的使用方式
  
    無論你是否相信ASPNET都使用HTTP請求實現了大量的自己的功能ASPNET使用處理程序來處理aspx asmx soap和其它ASPNET文件
  
    下面是nfig文件中的一個片段
  
   <httpHandlers>
   <add verb=* path=traceaxd type=SystemWebHandlersTraceHandler/>
   <add verb=* path=*aspx type=SystemWebUIPageHandlerFactory/>
   <add verb=* path=*ashx type=SystemWebUISimpleHandlerFactory/>
   <add verb=* path=nfig type=SystemWebHttpForbiddenHandler/>
   <add verb=GETHEAD path=* type=SystemWebStaticFileHandler/>
   
   
  </httpHandlers> 
   
  在上面的配置信息中你可以看到對aspx文件的所有請求都由SystemWebUIPageHandlerFactory類來處理與此類似nfig文件和其它文件(它們不能被客戶端直接訪問)的所有請求都由SystemWebHttpForbiddenHandler類處理你可能已經猜到當訪問這些文件的時候該類簡單地給客戶端返回一個錯誤信息
  
  執行HTTP處理程序 
   
  現在你將看到如何實現一個HTTP處理程序那麼我們的新處理程序要做什麼任務呢?前面我提到處理程序大多數用於給Web服務器添加新功能因此我將建立一個處理程序來處理新的文件類型——擴展名為seconds的文件我們建立了這個處理程序並在我們的Web應用程序的nfig文件中注冊之後所有對seconds文件的請求都將由這個新處理程序來處理 
   
  你可能正在考慮這個處理程序的使用方法如果你希望引入一種新的服務器腳本語言或動態服務器文件(例如aspaspx)該怎麼辦呢?你可以為它編寫一個自己的處理程序類似地如果你希望在IIS上運行Java小程序JSP和其它一些服務器端Java組件應該怎麼辦呢?一種方法是安裝某些ISAPI擴展(例如Allaire或Macromedia Jrun)你也可以編寫自己的HTTP處理程序盡管這對於第三方廠商(例如Allaire和Macromedia)來說是很復雜的事務但是它卻是個很有吸引力的選擇因為它們的HTTP處理能夠能夠訪問ASPNET運行時暴露的所有新功能
  
    實現我們的HTTP處理程序包含以下步驟
  
    編寫一個實現IHttpHandler接口的類
  
     在nfig或nfig文件中注冊這個處理程序
  
   在Internet服務管理器中把文件擴展(seconds)映射到ASPNET ISAPI擴展DLL(aspnet_isapidll)上
  
   第一步 
   
  在Visual StudioNET中建立一個新的C#類庫項目並把它命名為MyHandlerVisual StudioNET將自動地給項目添加一個叫做Classcs的類把它改名為NewHandler在代碼窗口中打開這個類並把類的名稱和構造函數的名稱改成NewHandler
  
    下面是NewHandler類的代碼
  
  using System;
  using SystemWeb;
  
  namespace MyHandler
  {
   public class NewHandler : IHttpHandler
   {
    public NewHandler()
    {
     // TODO: 此處添加構造邏輯
    }
  
    #region Implementation of IHttpHandler
    public void ProcessRequest(SystemWebHttpContext context)
    {
     HttpResponse objResponse = contextResponse ;
     objResponseWrite(<html><body><h>Hello Seconds Reader ) ;
     objResponseWrite(</body></html>) ;
    }
  
    public bool IsReusable
    {
     get
     {
      return true;
     }
    }
    #endregion
   }
  } 
   
  你在ProcessRequest方法中可以看到該HTTP處理程序通過SystemWebHttpContext對象訪問了所有作為參數傳遞給它的ASPNET內部對象實現ProcessRequest方法只需要簡單地從context對象中提取HttpResponse對象並把發送一些HTML給客戶端類似地IsReusable返回true表明這個處理程序可以被重復用作處理其它的HTTP請求
  
    我們編譯上面的代碼並把它放到webapp虛擬目錄的bin目錄之中
  
第二步
  
    在nfig文件中通過添加下面的文本來注冊這個處理程序
  
  <httpHandlers>
   <add verb=* path=*seconds type=MyHandlerNewHandlerMyHandler/>
  </httpHandlers>
  
第三步 
   
  由於我們已經建立了用於處理新擴展文件的處理程序了我們還需要把這個擴展名告訴IIS並把它映射到ASPNET如果你不執行這個步驟而試圖訪問Helloseconds文件IIS將簡單地返回該文件而不是把它傳遞給ASPNET運行時其結果是該HTTP處理程序不會被調用 
   
  運行Internet服務管理器右鍵點擊默認Web站點選擇屬性移動到Home目錄選項頁並點擊配置按鈕應用程序配置對話框彈出來了點擊添加按鈕並在可執行字段輸入aspnet_isapidll文件路徑在擴展字段輸入seconds其它字段不用處理該對話框如下所示 
    
  

  

  點擊確認按鈕關閉應用程序配置和默認Web站點屬性對話框

  現在我們運行Internet Explorer並輸入url看到的頁面如下


  HTTP處理程序中的對話狀態 
   
  維護對話狀態是Web應用程序執行的最通常的事務HTTP處理程序也需要訪問這些對話狀態但是HTTP處理程序的默認設置是沒有激活對話狀態的為了讀取和/或寫入狀態數據需要HTTP處理程序實現下面的接口之一
  
    · IRequiresSessionState
  
    · IReadOnlySessionState 
   
  當HTTP處理程序需要讀寫對話數據的時候它必須實現IRequiresSessionState接口如果它只讀取對話數據實現IReadOnlySessionState接口就可以了 
   
  這兩個接口都是標記接口並沒有包含任何方法因此如果你希望激活NewHandler處理程序的對話狀態要像下面的代碼一樣聲明NewHandler類
  
  public class NewHandler : IHttpHandler IRequiresSessionState
  
    HTTP模塊
  
    HTTP模塊是實現了SystemWebIhttpModule接口的NET組件這些組件通過在某些事件中注冊自身把自己插入ASPNET請求處理管道當這些事件發生的時候ASPNET調用對請求有興趣的HTTP模塊這樣該模塊就能處理請求了
  
    HTTP模塊實現了IhttpModule接口的下面一些方法 
   
  方法名稱描述Init 這個方法允許HTTP模塊向HttpApplication 對象中的事件注冊自己的事件處理程序 
Dispose 這個方法給予HTTP模塊在對象被垃圾收集之前執行清理的機會
  
    HTTP模塊可以向SystemWebHttpApplication對象暴露的下面一些方法注冊 
   
  事件名稱描述AcquireRequestState 當ASPNET運行時准備好接收當前HTTP請求的對話狀態的時候引發這個事件 
  AuthenticateRequest 當ASPNET 運行時准備驗證用戶身份的時候引發這個事件 
  AuthorizeRequest 當ASPNET運行時准備授權用戶訪問資源的時候引發這個事件 
  BeginRequest 當ASPNET運行時接收到新的HTTP請求的時候引發這個事件 
  Disposed 當ASPNET完成HTTP請求的處理過程時引發這個事件 
  EndRequest 把響應內容發送到客戶端之前引發這個事件 
  Error 在處理HTTP請求的過程中出現未處理異常的時候引發這個事件 
  PostRequestHandlerExecute 在HTTP處理程序結束執行的時候引發這個事件 
  PreRequestHandlerExecute 在ASPNET開始執行HTTP請求的處理程序之前引發這個事件在這個事件之後ASPNET 把該請求轉發給適當的HTTP處理程序 

  PreSendRequestContent 在ASPNET把響應內容發送到客戶端之前引發這個事件這個事件允許我們在內容到達客戶端之前改變響應內容我們可以使用這個事件給頁面輸出添加用於所有頁面的內容例如通用菜單頭信息或腳信息 

  PreSendRequestHeaders 在ASPNET把HTTP響應頭信息發送給客戶端之前引發這個事件在頭信息到達客戶端之前這個事件允許我們改變它的內容我們可以使用這個事件在頭信息中添加cookie和自定義數據 
  
  ReleaseRequestState 當ASPNET結束所搜有的請求處理程序執行的時候引發這個事件 

  ResolveRequestCache 我們引發這個事件來決定是否可以使用從輸出緩沖返回的內容來結束請求這依賴於Web應用程序的輸出緩沖時怎樣設置的 

  UpdateRequestCache 當ASPNET完成了當前的HTTP請求的處理並且輸出內容已經准備好添加給輸出緩沖的時候引發這個事件這依賴於Web應用程序的輸出緩沖是如何設置的 
   
  除了這些事件之外我們還可以使用四個事件我們可以通過實現Web應用程序的globalasax文件中一些方法來使用這些事件
  
    這些事件是
  
    · Application_OnStart
  
    當第一個請求到達Web應用程序的時候引發這個事件
  
    · Application_OnEnd
  
    准備終止應用程序之前引發這個事件
  
    · Session_OnStart
  
    用戶對話的第一個請求引發這個事件
  
    · Session_OnEnd
  
    放棄對話或者對話超期的時候引發這個事件


From:http://tw.wingwit.com/Article/program/net/201311/11664.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.