溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何進行HttpHandler與HttpModule的分析與應用

發(fā)布時間:2021-10-29 16:50:51 來源:億速云 閱讀:108 作者:柒染 欄目:編程語言

這篇文章將為大家詳細講解有關如何進行HttpHandler與HttpModule的分析與應用,文章內(nèi)容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

神秘的HttpHandler與HttpModule

大學時候我是從拖控件開始學習asp.net的,對.net的很多類庫對象都不是很了解。所以看到大家寫一些個性的asp.net名詞,就感覺asp.net總有一層神秘的面紗籠罩著,讓我琢磨不透,相信園子里面也有很多和我經(jīng)歷差不多的.net攻城師。在以前看HttpHandler與HttpModule都是神秘莫測的。哈哈,今天我為大家展示下我對他的理解,以及應用。

也許你不懂HttpHandler與HttpModule(大俠Return),也許你不知道HttpHandler與HttpModule的用途,也許你似懂非懂。今天,請讓我?guī)ьI大家去領略一下HttpHandler與HttpModule的風采,今天我要讓他變得So Easy ??!

理解asp.net管線事件

何謂asp.net管線?簡單的說就是頁面的生命周期,就是頁面從你開始請求到展現(xiàn)在你的瀏覽器期間,asp.net所做的一系列事件。下面給你展現(xiàn)下這些事件(參見與Fish Li)。

1. 對請求進行驗證,將檢查瀏覽器發(fā)送的信息,并確定其是否包含潛在惡意標記。 有關更多信息,請參見 ValidateRequest 和腳本侵入概述。

2. 如果已在 Web.config 文件的 UrlMappingsSection 節(jié)中配置了任何 URL,則執(zhí)行 URL 映射。

3. 引發(fā) BeginRequest 事件。

4. 引發(fā) AuthenticateRequest 事件。

5. 引發(fā) PostAuthenticateRequest 事件。

6. 引發(fā) AuthorizeRequest 事件。

7. 引發(fā) PostAuthorizeRequest 事件。

8. 引發(fā) ResolveRequestCache 事件。

9. 引發(fā) PostResolveRequestCache 事件。

10. 根據(jù)所請求資源的文件擴展名(在應用程序的配置文件中映射),選擇實現(xiàn) IHttpHandler 的類,對請求進行處理。 如果該請求針對從 Page 類派生的對象(頁),并且需要對該頁進行編譯,則 ASP.NET 會在創(chuàng)建該頁的實例之前對其進行編譯。

11. 引發(fā) PostMapRequestHandler 事件。

12. 引發(fā) AcquireRequestState 事件。

13. 引發(fā) PostAcquireRequestState 事件。

14. 引發(fā) PreRequestHandlerExecute 事件。

15. 為該請求調(diào)用合適的 IHttpHandler 類的 ProcessRequest 方法(或異步版 IHttpAsyncHandler.BeginProcessRequest)。 例如,如果該請求針對某頁,則當前的頁實例將處理該請求。

16. 引發(fā) PostRequestHandlerExecute 事件。

17. 引發(fā) ReleaseRequestState 事件。

18. 引發(fā) PostReleaseRequestState 事件。

19. 如果定義了 Filter 屬性,則執(zhí)行響應篩選。

20. 引發(fā) UpdateRequestCache 事件。

21. 引發(fā) PostUpdateRequestCache 事件。

22. 引發(fā) EndRequest 事件。

23. 引發(fā) PreSendRequestHeaders 事件。

24. 引發(fā) PreSendRequestContent 事件。

注意:

1.記著上面這些事件,不是瞎寫的,他們的順序更不是瞎寫的。是頁面從開始請求到頁面展現(xiàn)結束,他們是從一到二十四,從上到下,依次觸發(fā)的。

2.從BeginRequest開始的事件,并不是每個事件都會被觸發(fā),因為在整個處理過程中,隨時可以調(diào)用Response.End() 或者有未處理的異常發(fā)生而提前結束整個過程。所有事件中,只有EndRequest事件是肯定會觸發(fā)的, (部分Module的)BeginRequest有可能也不會被觸發(fā)。

3.如果是IIS7,第10個事件也就是MapRequestHandler事件,而且在EndRequest 事件前,還增加了另二個事件:LogRequest 和 PostLogRequest 。只有當應用程序在 IIS 7.0 集成模式下運行,并且與 .NET Framework 3.0 或更高版本一起運行時,才會支持 MapRequestHandler、LogRequest 和 PostLogRequest 事件。

總結:這些事件我們可以隨意在你需要的事件中添加方法,類,屬性等一些列屬于你自己對請求的操作。也就是說我們以前都是在頁面級編程,現(xiàn)在,我們可以在請求級處理項目,處理請求。具體怎么做,要看下面的HttpMoudle和HttpHandler的神奇功效了。

理解HttpHandler與HttpModule

先說HttpHandler。

首先你應該明白asp.net是怎么處理我們的請求文件的,這里不扯與asp.net無足輕重的看似更加底層的神秘面紗,那么.net是怎么處理我們的請求文件的呢?給你看個東西。

打開你電腦上C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG\ 目錄下的web.config 文件。找到httpHandlers節(jié)點,看他下面都寫了什么。你不想打開的話看我的。

<httpHandlers>        <add verb="*" path="*.rules" type="System.Web.HttpForbiddenHandler" validate="true"/>        <add verb="*" path="*.xoml" type="System.ServiceModel.Activation.HttpHandler, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="false"/>              <add path="*.svc" verb="*" type="System.ServiceModel.Activation.HttpHandler, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="false"/>              <add path="trace.axd" verb="*" type="System.Web.Handlers.TraceHandler" validate="True"/>              <add path="WebResource.axd" verb="GET" type="System.Web.Handlers.AssemblyResourceLoader" validate="True"/>              <add path="*.axd" verb="*" type="System.Web.HttpNotFoundHandler" validate="True"/>              <add path="*.aspx" verb="*" type="System.Web.UI.PageHandlerFactory" validate="True"/>              <add path="*.ashx" verb="*" type="System.Web.UI.SimpleHandlerFactory" validate="True"/>              <add path="*.asmx" verb="*" type="System.Web.Services.Protocols.WebServiceHandlerFactory, System.Web.Services, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" validate="False"/>              <add path="*.rem" verb="*" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="False"/>              <add path="*.soap" verb="*" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="False"/>              <add path="*.asax" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.ascx" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.master" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.skin" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.browser" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.sitemap" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.dll.config" verb="GET,HEAD" type="System.Web.StaticFileHandler" validate="True"/>              <add path="*.exe.config" verb="GET,HEAD" type="System.Web.StaticFileHandler" validate="True"/>              <add path="*.config" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.cs" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.csproj" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.vb" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.vbproj" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.webinfo" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.licx" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.resx" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.resources" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.mdb" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.vjsproj" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.java" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.jsl" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.ldb" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.ad" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.dd" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.ldd" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.sd" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.cd" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.adprototype" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.lddprototype" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.sdm" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.sdmDocument" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.mdf" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.ldf" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.exclude" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*.refresh" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>              <add path="*" verb="GET,HEAD,POST" type="System.Web.DefaultHttpHandler" validate="True"/>              <add path="*" verb="*" type="System.Web.HttpMethodNotAllowedHandler" validate="True"/>          </httpHandlers>

上面這段代碼是這樣理解的:在<httpHandlers>結點中將不同的文件類型映射給不同的Handler去處理,對于.aspx來說,是由System.Web.UI.PageHandlerFactory來處理。而對于.cs來說,是由System.Web.HttpForbiddenHandler 處理....

上面的是默認Handler處理,當然知道了HttpHandler之后,我們也可以自己注冊自己的HttpHandler,寫自己的HttpHandler處理程序,處理不同類型的文件,這個等會兒我實現(xiàn)下,給大家看看。

問題: 既然HttpHandler的作用是將請求中,各個不同類型后綴名的文件,映射給不同的處理程序去處理,那么處理程序是在頁面生命周期中的那個時間中映射處理請求的呢?

答: 依照上面的24個事件,這個HttpHandler節(jié)點中的映射是在第10個步驟中觸發(fā)的。而他映射給不同的處理程序,這些處理程序中方法、類的實現(xiàn)是在第15步觸發(fā)的。

再說HttpModule。

HttpHandler是針對一類型的文件,映射給指定的處理程序對請求進行出來。并且映射,與處理都發(fā)生在asp.net已經(jīng)指定好的事件中。

而HttpModule則是針對所有的請求文件,映射給指定的處理程序對請求進行處理,而這些處理,可以發(fā)生在請求管線中的任何一個事件中。也就是說你訂閱哪個事件,這寫處理就發(fā)生于那個事件中,處理過后再執(zhí)行,你訂閱過的事件的下一個事件,當然你也可以終止所有事件直接運行***一個事件,這就意味這他可以不給HttpHandler機會,很牛的HttpModule。

HttpHandler的使用

HttpHandler的使用通過一種防盜鏈技術來演示

1.首先注冊HttpHandler:在Web.config中注冊

<httpHandlers>                  <!--映射jpg格式的文件,給ProcessHandler_test.CustomHandler處理。-->                  <!--type里面逗號之前 命名空間加類名(ProcessHandler_test.CustomHandler),后面程序集名稱-->                  <add path="*.jpg" verb="*" type="httphander_test.CustomHandler, ProcessHandler_test" />              </httpHandlers>

上面注冊是把網(wǎng)站中請求jpg格式文件的請求,映射給命名空間為httphander_test類名為CustomHandler的程序集ProcessHandler_test來處理請求。

2.如果想通過HttpHandler處理請求,必須在映射的處理程序中實現(xiàn)接口IHttpHandler

3.映射到的程序代碼如下

namespace httphander_test  {      public class CustomHandler :IHttpHandler      {          public void ProcessRequest(HttpContext context)          {              // 獲取文件服務器端物理路徑              string FileName = context.Server.MapPath(context.Request.FilePath);              // 如果UrlReferrer為空,則顯示一張默認的禁止盜鏈的圖片              if (context.Request.UrlReferrer.Host == null)              {                  context.Response.ContentType = "image/gif";                  context.Response.WriteFile("/error.gif");              }              else             {                  // 如果 UrlReferrer中不包含自己站點主機域名,則顯示一張默認的禁止盜鏈的圖片                  if (context.Request.UrlReferrer.Host.IndexOf("yourdomain.com") > 0)                  {                      context.Response.ContentType = "image/gif";                      context.Response.WriteFile(FileName);                  }                  else                 {                      context.Response.ContentType = "image/gif";                      context.Response.WriteFile("/error.gif");                  }              }          }           public bool IsReusable          {              get { throw new NotImplementedException(); }          }      }  }

上面這個簡單的實例就完成了,如果有Jpg格式文件的請求,而不是在本網(wǎng)站的域名中請求,那么就會輸出一個指定的錯誤圖片來替換原連接圖片。

總結:httpHandler的功能遠不止這些,希望你能理解他是對一類文件請求的處理,也希望你能理解他在請求管道中的事件位置,這樣對您理解會更有幫助。

HttpModule的使用

由于HttpModule過于強大的功能,也就是說任何一個請求都要經(jīng)過注冊過的HttpModule處理程序,所以大家在用他的時候一定要對各種請求做好判斷,也就是處理什么請求,就讓這個請求走那個處理程序,不要讓他每個方法,都去執(zhí)行。要不會讓程序負重,得不償失。

使用HttpModule跟HttpHandler的步驟類似,而HttpModule實現(xiàn)的是IHttpModule接口。

關于如何進行HttpHandler與HttpModule的分析與應用就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI