ASP.NET處理HTTP請(qǐng)求的流程:IHttpModule、IHttpHandler與管道事件
一、ASP.NET處理管道
- Asp.net處理管道的第一步是創(chuàng)建HttpWorkerRequest對(duì)象,它包含于當(dāng)前請(qǐng)求有關(guān)的所有信息。
- HttpWorkerRequest把請(qǐng)求傳遞給HttpRuntime類的靜態(tài)ProcessRequest方法。HttpRuntime首先要做的事是創(chuàng)建HttpContext對(duì)象,并用HttpWorkerRequest進(jìn)行初始化。
- 創(chuàng)建了HttpContext實(shí)例之后,HttpRuntime類就通過調(diào)用HttpApplicationFactory的靜態(tài)GetApplicationInstance()方法,為該應(yīng)用程序請(qǐng)求HttpApplication派生類的一個(gè)示例。GetApplicationInstance()方法要么創(chuàng)建一個(gè)HttpApplication類的一個(gè)新實(shí)例,要么從應(yīng)用程序?qū)ο蟪刂腥〕鲆粋€(gè)實(shí)例。
- 在創(chuàng)建完成HttpApplication實(shí)例之后,就對(duì)它進(jìn)行初始化,并在初始化期間分配應(yīng)用程序定義的所
- 有模塊。模塊式實(shí)現(xiàn)IHttpModule接口的類,作用就是為了實(shí)現(xiàn)那經(jīng)典的19個(gè)標(biāo)準(zhǔn)處理事件。
- 在創(chuàng)建了模塊之后,HttpRuntime類通過調(diào)用它的BeginProcessRequest方法,要求最新檢索到的HttpApplication類對(duì)當(dāng)前請(qǐng)求提供服務(wù)。然后,為當(dāng)前請(qǐng)求找到合適的處理程序工廠。
- 創(chuàng)建處理程序,傳遞當(dāng)前HttpContext,一旦ProcessRequest方法返回,請(qǐng)求完成。

二、IHttpHandler
HttpHandler是asp.net真正處理Http請(qǐng)求的地方。在這個(gè)HttpHandler容器中,ASP.NET Framework才真正地對(duì)客戶端請(qǐng)求的服務(wù)器頁面做出編譯和執(zhí)行,并將處理過后的信息附加在HTTP請(qǐng)求信息流中再次返回到HttpModule中。
當(dāng)一個(gè)HTTP請(qǐng)求經(jīng)過HttpModule容器傳遞到HttpHandler容器中時(shí),ASP.NET Framework會(huì)調(diào)用HttpHandler的ProcessRequest成員方法來對(duì)這個(gè)HTTP請(qǐng)求進(jìn)行真正的處理。并將處理完成的結(jié)果繼續(xù)經(jīng)由HttpModule傳遞下去,直至到達(dá)客戶端。
HttpHandler與HttpModule不同,一旦定義了自己的HttpHandler類,那么它對(duì)系統(tǒng)的HttpHandler的關(guān)系將是“覆蓋”關(guān)系。

應(yīng)用1:圖片防盜鏈(實(shí)現(xiàn)一個(gè)自定義的IHttpHandler)
第一:定義一個(gè)實(shí)現(xiàn)了IHttpHandler的類,并且實(shí)現(xiàn)其ProcessRequest方法。在一個(gè)HttpHandler容器中如果需要訪問Session,必須實(shí)現(xiàn)IRequiresSessionState接口,這只是一個(gè)標(biāo)記接口,沒有任何方法。
public class PictureHttpHandler : IHttpHandler
{
public bool IsReusable
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
//站點(diǎn)的域名
string myDomain = "localhost";
if (context.Request.UrlReferrer == null ||
context.Request.UrlReferrer.Host.ToLower().IndexOf(myDomain) < 0)
{
//如果是通過瀏覽器直接訪問或者是通過其他站點(diǎn)訪問過來的,則顯示“資源不存在”圖片
context.Response.ContentType = "image/JPEG";
context.Response.WriteFile(context.Request.PhysicalApplicationPath + "/images/noimg.jpg");
}
else
{
//如果是通過站內(nèi)訪問的,這正常顯示圖片
context.Response.ContentType = "image/JPEG";
context.Response.WriteFile(context.Request.PhysicalPath);
}
}
}第二:在web.config中注冊(cè)這個(gè)類,并且指定Handler處理的請(qǐng)求類型,把此節(jié)點(diǎn)插入system.web節(jié)點(diǎn)中
<httpHandlers>
<!--path中指定的是執(zhí)行type中HttpHandler的訪問路徑。此路徑可以帶后綴也可以不帶后綴。如果path配置為*,則會(huì)對(duì)所有的請(qǐng)求執(zhí)行此HttpHandler-->
<add verb="*" path="*.jpg" type="MyHttpHandler.PictureHttpHandler,MyHttpHandler"/>
</httpHandlers>正常訪問default頁面時(shí):

通過圖片地址直接訪問時(shí):

應(yīng)用2、生成驗(yàn)證碼
public class ValidateCodeHttpHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "image/gif";
//建立Bitmap對(duì)象,繪圖
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();
//添加隨機(jī)的五個(gè)字母
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();
//如果沒有實(shí)現(xiàn)IRequiresSessionState,則這里會(huì)出錯(cuò),也無法生成圖片
context.Response.End();
}
public bool IsReusable
{
get { return true; }
}
}把下面的項(xiàng)加到web.config中的httphandler節(jié)點(diǎn)中:
<add verb="*" path="validatevode" type="MyHttpHandler.ValidateCodeHttpHandler,MyHttpHandler"/>
訪問validatevode時(shí):

三、自定義HttpModule:
每次請(qǐng)求的開始和結(jié)束定義的HttpModule。
在Asp.net中,創(chuàng)建在System.Web命名空間下的IHttpModule接口專門用來定義HttpApplication對(duì)象的事件處理。實(shí)現(xiàn)IHttpModule接口的類稱為HttpModule(Http模塊)。
1、通過IHttpModule創(chuàng)建HttpApplication的事件處理程序
public class ModuleExample : IHttpModule
{
public void Init(System.Web.HttpApplication application)
{
application.PostAuthenticateRequest += (sender, args) =>
{
HttpContext context = ((HttpApplication)sender).Context;
context.Response.Write("請(qǐng)求PostAuthenticate");
};
application.BeginRequest += (sender, args) =>
{
HttpContext context = ((HttpApplication)sender).Context;
context.Response.Write("請(qǐng)求到達(dá)");
};
application.EndRequest += (sender, args) =>
{
HttpContext context = ((HttpApplication)sender).Context;
context.Response.Write("請(qǐng)求結(jié)束");
};
}
public void Dispose()
{
throw new NotImplementedException();
}
}2、注冊(cè)HttpModule
在Asp.net中,實(shí)現(xiàn)IHttpModule接口只是實(shí)現(xiàn)HttpModule的第一步,在Asp.net中所使用的HttpModule還必須在網(wǎng)站配置文件中進(jìn)行注冊(cè)才能真正生效,并在Asp.net中使用。
<system.webServer>
<modules>
<add name="ModuleExample" type="Samples.ModeleExample">
</modules>
</system.webServer>3、常見的HttpModule
在Asp.net中,已經(jīng)預(yù)定義了許多HttpModule,甚至已經(jīng)在服務(wù)器的網(wǎng)站配置文件中進(jìn)行了注冊(cè),在系統(tǒng)文件夾C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\web.config中看到已經(jīng)注冊(cè)的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>以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- ASP.NET Core使用IHttpClientFactory發(fā)出HTTP請(qǐng)求
- ASP.NET Core擴(kuò)展庫之Http請(qǐng)求模擬功能的使用
- 在ASP.NET Core中用HttpClient發(fā)送POST, PUT和DELETE請(qǐng)求
- ASP.NET Core中間件計(jì)算Http請(qǐng)求時(shí)間示例詳解
- ASP.NET Core中調(diào)整HTTP請(qǐng)求大小的幾種方法詳解
- asp.net 請(qǐng)求輸入到輸出的全過程及httpHandler和httpModuler詳細(xì)介紹
- Asp.net使用HttpModule壓縮并刪除空白Html請(qǐng)求的實(shí)現(xiàn)代碼
- asp.net 截取Http請(qǐng)求的實(shí)現(xiàn)代碼
相關(guān)文章
連接ACCESS數(shù)據(jù)庫時(shí)發(fā)生錯(cuò)誤提示:找不到可安裝的 ISAM
連接ACCESS數(shù)據(jù)庫時(shí)發(fā)生錯(cuò)誤提示:找不到可安裝的 ISAM 檢查后發(fā)現(xiàn)原來是把Data Source寫成 DataSource了2011-04-04
ASP.NET系統(tǒng)關(guān)鍵字及保留字列表整理
ASP.NET系統(tǒng)關(guān)鍵字及保留字列表,大家在寫程序的時(shí)候一定要避免使用,免得引起不需要的麻煩2012-10-10
讓Sqlite脫離VC++ Runtime獨(dú)立運(yùn)行的方法
這篇文章主要介紹了讓Sqlite脫離VC++ Runtime獨(dú)立運(yùn)行的方法,需要的朋友可以參考下2014-07-07
C#命名空間System.ComponentModel屬性方法匯總
本文詳細(xì)講解了C#命名空間System.ComponentModel屬性方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-01-01
創(chuàng)建ASP.NET?Core?Web應(yīng)用程序并介紹項(xiàng)目模板
這篇文章介紹了創(chuàng)建ASP.NET?Core?Web應(yīng)用程序的方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-02-02
ASP.NET Core應(yīng)用程序配置文件AppSetting.json
這篇文章介紹了ASP.NET Core應(yīng)用程序配置文件AppSetting.json,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-02-02
.Net行為型設(shè)計(jì)模式之狀態(tài)模式(State)
這篇文章介紹了.Net行為型設(shè)計(jì)模式之狀態(tài)模式(State),文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05

