理解asp.net管線事件
何謂asp.net管線?簡單的說就是頁面的生命週期,就是頁面從你開始請求到展示在你的瀏覽器期間,asp.net所作的一系列事件。下面給你展示下這些事件(參見與Fish Li)。java
1. 對請求進行驗證,將檢查瀏覽器發送的信息,並肯定其是否包含潛在惡意標記。 有關更多信息,請參見 ValidateRequest 和腳本侵入概述。 2. 若是已在 Web.config 文件的 UrlMappingsSection 節中配置了任何 URL,則執行 URL 映射。 3. 引起 BeginRequest 事件。 4. 引起 AuthenticateRequest 事件。 5. 引起 PostAuthenticateRequest 事件。 6. 引起 AuthorizeRequest 事件。 7. 引起 PostAuthorizeRequest 事件。 8. 引起 ResolveRequestCache 事件。 9. 引起 PostResolveRequestCache 事件。 10. 根據所請求資源的文件擴展名(在應用程序的配置文件中映射),選擇實現 IHttpHandler 的類,對請求進行處理。 若是該請求針對從 Page 類派生的對象 (頁),而且須要對該頁進行編譯,則 ASP.NET 會在建立該頁的實例以前對其進行編譯。 11. 引起 PostMapRequestHandler 事件。 12. 引起 AcquireRequestState 事件。 13. 引起 PostAcquireRequestState 事件。 14. 引起 PreRequestHandlerExecute 事件。 15. 爲該請求調用合適的 IHttpHandler 類的 ProcessRequest 方法(或異步版 IHttpAsyncHandler.BeginProcessRequest)。 例如,若是該請求針對某頁,則 當前的頁實例將處理該請求。 16. 引起 PostRequestHandlerExecute 事件。 17. 引起 ReleaseRequestState 事件。 18. 引起 PostReleaseRequestState 事件。 19. 若是定義了 Filter 屬性,則執行響應篩選。 20. 引起 UpdateRequestCache 事件。 21. 引起 PostUpdateRequestCache 事件。 22. 引起 EndRequest 事件。 23. 引起 PreSendRequestHeaders 事件。 24. 引起 PreSendRequestContent 事件。
1.記着上面這些事件,不是瞎寫的,他們的順序更不是瞎寫的。是頁面從開始請求到頁面展示結束,他們是從一到二十四,從上到下,依次觸發的。 注意:web
2.從BeginRequest開始的事件,並非每一個事件都會被觸發,由於在整個處理過程當中,隨時能夠調用Response.End() 或者有未處理的異常發生而提早結束整個過程。全部事件中,只有EndRequest事件是確定會觸發的, (部分Module的)BeginRequest有可能也不會被觸發。編程
3.若是是IIS7,第10個事件也就是MapRequestHandler事件,並且在EndRequest 事件前,還增長了另二個事件:LogRequest 和 PostLogRequest 。只有當應用程序在 IIS 7.0 集成模式下運行,而且與 .NET Framework 3.0 或更高版本一塊兒運行時,纔會支持 MapRequestHandler、LogRequest 和 PostLogRequest 事件。瀏覽器
總結:這些事件咱們能夠隨意在你須要的事件中添加方法,類,屬性等一些列屬於你本身對請求的操做。也就是說咱們之前都是在頁面級編程,如今,咱們能夠在請求級處理項目,處理請求。具體怎麼作,要看下面的HttpMoudle和HttpHandler的神奇功效了。服務器
理解HttpHandler與HttpModule
先說HttpHandler。app
首先你應該明白asp.net是怎麼處理咱們的請求文件的,這裏不扯與asp.net無足輕重的看似更加底層的神祕面紗,那麼.net是怎麼處理咱們的請求文件的呢?給你看個東西。asp.net
打開你電腦上C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG\ 目錄下的web.config 文件。找到httpHandlers節點,看他下面都寫了什麼。你不想打開的話看個人。 dom
<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處理程序,處理不一樣類型的文件,這個等會兒我實現下,給你們看看。jsp
問題: 既然HttpHandler的做用是將請求中,各個不一樣類型後綴名的文件,映射給不一樣的處理程序去處理,那麼處理程序是在頁面生命週期中的那個時間中映射處理請求的呢?
答: 依照上面的24個事件,這個HttpHandler節點中的映射是在第10個步驟中觸發的。而他映射給不一樣的處理程序,這些處理程序中方法、類的實現是在第15步觸發的。
再說HttpModule。
HttpHandler是針對一類型的文件,映射給指定的處理程序對請求進行出來。而且映射,與處理都發生在asp.net已經指定好的事件中。
而HttpModule則是針對全部的請求文件,映射給指定的處理程序對請求進行處理,而這些處理,能夠發生在請求管線中的任何一個事件中。也就是說你訂閱哪一個事件,這寫處理就發生於那個事件中,處理事後再執行,你訂閱過的事件的下一個事件,固然你也能夠終止全部事件直接運行最後一個事件,這就意味這他能夠不給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>
上面註冊是把網站中請求jpg格式文件的請求,映射給命名空間爲httphander_test類名爲CustomHandler的程序集ProcessHandler_test來處理請求。
2.若是想經過HttpHandler處理請求,必須在映射的處理程序中實現接口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格式文件的請求,而不是在本網站的域名中請求,那麼就會輸出一個指定的錯誤圖片來替換原鏈接圖片。
總結:httpHandler的功能遠不止這些,但願你能理解他是對一類文件請求的處理,也但願你能理解他在請求管道中的事件位置,這樣對您理解會更有幫助。
HttpModule的使用
因爲HttpModule過於強大的功能,也就是說任何一個請求都要通過註冊過的HttpModule處理程序,因此你們在用他的時候必定要對各類請求作好判斷,也就是處理什麼請求,就讓這個請求走那個處理程序,不要讓他每一個方法,都去執行。要不會讓程序負重,得不償失。
使用HttpModule跟HttpHandler的步驟相似,而HttpModule實現的是IHttpModule接口。