ASP.NET處理HTTP請求的流程:IHttpModule、IHttpHandler與管道事件
一、ASP.NET處理管道
- Asp.net處理管道的第一步是創建HttpWorkerRequest對象,它包含於當前請求有關的所有信息。
- HttpWorkerRequest把請求傳遞給HttpRuntime類的靜態ProcessRequest方法。HttpRuntime首先要做的事是創建HttpContext對象,並用HttpWorkerRequest進行初始化。
- 創建瞭HttpContext實例之後,HttpRuntime類就通過調用HttpApplicationFactory的靜態GetApplicationInstance()方法,為該應用程序請求HttpApplication派生類的一個示例。GetApplicationInstance()方法要麼創建一個HttpApplication類的一個新實例,要麼從應用程序對象池中取出一個實例。
- 在創建完成HttpApplication實例之後,就對它進行初始化,並在初始化期間分配應用程序定義的所
- 有模塊。模塊式實現IHttpModule接口的類,作用就是為瞭實現那經典的19個標準處理事件。
- 在創建瞭模塊之後,HttpRuntime類通過調用它的BeginProcessRequest方法,要求最新檢索到的HttpApplication類對當前請求提供服務。然後,為當前請求找到合適的處理程序工廠。
- 創建處理程序,傳遞當前HttpContext,一旦ProcessRequest方法返回,請求完成。
二、IHttpHandler
HttpHandler是asp.net真正處理Http請求的地方。在這個HttpHandler容器中,ASP.NET Framework才真正地對客戶端請求的服務器頁面做出編譯和執行,並將處理過後的信息附加在HTTP請求信息流中再次返回到HttpModule中。
當一個HTTP請求經過HttpModule容器傳遞到HttpHandler容器中時,ASP.NET Framework會調用HttpHandler的ProcessRequest成員方法來對這個HTTP請求進行真正的處理。並將處理完成的結果繼續經由HttpModule傳遞下去,直至到達客戶端。
HttpHandler與HttpModule不同,一旦定義瞭自己的HttpHandler類,那麼它對系統的HttpHandler的關系將是“覆蓋”關系。
應用1:圖片防盜鏈(實現一個自定義的IHttpHandler)
第一:定義一個實現瞭IHttpHandler的類,並且實現其ProcessRequest方法。在一個HttpHandler容器中如果需要訪問Session,必須實現IRequiresSessionState接口,這隻是一個標記接口,沒有任何方法。
public class PictureHttpHandler : IHttpHandler { public bool IsReusable { get { return true; } } public void ProcessRequest(HttpContext context) { //站點的域名 string myDomain = "localhost"; if (context.Request.UrlReferrer == null || context.Request.UrlReferrer.Host.ToLower().IndexOf(myDomain) < 0) { //如果是通過瀏覽器直接訪問或者是通過其他站點訪問過來的,則顯示“資源不存在”圖片 context.Response.ContentType = "image/JPEG"; context.Response.WriteFile(context.Request.PhysicalApplicationPath + "/images/noimg.jpg"); } else { //如果是通過站內訪問的,這正常顯示圖片 context.Response.ContentType = "image/JPEG"; context.Response.WriteFile(context.Request.PhysicalPath); } } }
第二:在web.config中註冊這個類,並且指定Handler處理的請求類型,把此節點插入system.web節點中
<httpHandlers> <!--path中指定的是執行type中HttpHandler的訪問路徑。此路徑可以帶後綴也可以不帶後綴。如果path配置為*,則會對所有的請求執行此HttpHandler--> <add verb="*" path="*.jpg" type="MyHttpHandler.PictureHttpHandler,MyHttpHandler"/> </httpHandlers>
正常訪問default頁面時:
通過圖片地址直接訪問時:
應用2、生成驗證碼
public class ValidateCodeHttpHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "image/gif"; //建立Bitmap對象,繪圖 Bitmap basemap = new Bitmap(200, 60); Graphics graph = Graphics.FromImage(basemap); graph.FillRectangle(new SolidBrush(Color.White), 0, 0, 200, 60); Font font = new Font(FontFamily.GenericSerif, 48, FontStyle.Bold, GraphicsUnit.Pixel); Random r = new Random(); string letters = "ABCDEFGHIJKLMNPQRSTUVWXYZ"; string letter; StringBuilder s = new StringBuilder(); //添加隨機的五個字母 for (int x = 0; x < 5; x++) { letter = letters.Substring(r.Next(0, letters.Length - 1), 1); s.Append(letter); graph.DrawString(letter, font, new SolidBrush(Color.Black), x * 38, r.Next(0, 15)); } //混淆背景 Pen linePen = new Pen(new SolidBrush(Color.Black), 2); for (int x = 0; x < 6; x++) graph.DrawLine(linePen, new Point(r.Next(0, 199), r.Next(0, 59)), new Point(r.Next(0, 199), r.Next(0, 59))); //將圖片保存到輸出流中 basemap.Save(context.Response.OutputStream, ImageFormat.Gif); //context.Session["CheckCode"] = s.ToString(); //如果沒有實現IRequiresSessionState,則這裡會出錯,也無法生成圖片 context.Response.End(); } public bool IsReusable { get { return true; } } }
把下面的項加到web.config中的httphandler節點中:
<add verb="*" path="validatevode" type="MyHttpHandler.ValidateCodeHttpHandler,MyHttpHandler"/>
訪問validatevode時:
三、自定義HttpModule:
每次請求的開始和結束定義的HttpModule。
在Asp.net中,創建在System.Web命名空間下的IHttpModule接口專門用來定義HttpApplication對象的事件處理。實現IHttpModule接口的類稱為HttpModule(Http模塊)。
1、通過IHttpModule創建HttpApplication的事件處理程序
public class ModuleExample : IHttpModule { public void Init(System.Web.HttpApplication application) { application.PostAuthenticateRequest += (sender, args) => { HttpContext context = ((HttpApplication)sender).Context; context.Response.Write("請求PostAuthenticate"); }; application.BeginRequest += (sender, args) => { HttpContext context = ((HttpApplication)sender).Context; context.Response.Write("請求到達"); }; application.EndRequest += (sender, args) => { HttpContext context = ((HttpApplication)sender).Context; context.Response.Write("請求結束"); }; } public void Dispose() { throw new NotImplementedException(); } }
2、註冊HttpModule
在Asp.net中,實現IHttpModule接口隻是實現HttpModule的第一步,在Asp.net中所使用的HttpModule還必須在網站配置文件中進行註冊才能真正生效,並在Asp.net中使用。
<system.webServer> <modules> <add name="ModuleExample" type="Samples.ModeleExample"> </modules> </system.webServer>
3、常見的HttpModule
在Asp.net中,已經預定義瞭許多HttpModule,甚至已經在服務器的網站配置文件中進行瞭註冊,在系統文件夾C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\web.config中看到已經註冊的HttpModule如下:
<httpModules> <add name="OutputCache" type="System.Web.Caching.OutputCacheModule" /> <add name="Session" type="System.Web.SessionState.SessionStateModule" /> <add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule" /> <add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" /> <add name="PassportAuthentication" type="System.Web.Security.PassportAuthenticationModule" /> <add name="RoleManager" type="System.Web.Security.RoleManagerModule" /> <add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" /> <add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule" /> <add name="AnonymousIdentification" type="System.Web.Security.AnonymousIdentificationModule" /> <add name="Profile" type="System.Web.Profile.ProfileModule" /> <add name="ErrorHandlerModule" type="System.Web.Mobile.ErrorHandlerModule, System.Web.Mobile, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> <add name="ServiceModel" type="System.ServiceModel.Activation.HttpModule, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> <add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" /> <add name="ScriptModule-4.0" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> </httpModules>
以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持LevelAH。
推薦閱讀:
- ASP.NET MVC實現路由功能
- ASP.NET中HttpContext對象下的屬性介紹
- 詳解ASP.NET MVC的整個生命周期
- .NET API 接口數據傳輸加密最佳實踐記錄
- ASP.NET Core實現中間件的幾種方式