日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

ASP.NET-自定义HttpModule与HttpHandler

發(fā)布時(shí)間:2024/9/20 56 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ASP.NET-自定义HttpModule与HttpHandler 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在之前的ASP.NET是如何在IIS下工作的這篇文章中介紹了ASP.NET與IIS配合工作的機(jī)制,在http請(qǐng)求經(jīng)過(guò)一系列處理后,最后到達(dá)ASP.NET管道中,這時(shí),就是Http Modules和HttpHandler出場(chǎng)的時(shí)候了。

  再來(lái)擺出管道工作時(shí)序圖來(lái)一看:

HttpModule

HttpModule是類似于過(guò)濾器的作用,可以沒有,也可以有任意個(gè),每一個(gè)都可以訂閱管道事件中的任意個(gè)事件,在每個(gè)訂閱的事件中可自定義功能實(shí)現(xiàn)。

HttpModule是實(shí)現(xiàn)IHttpModule接口的類。接口如下:

  • public?interface?IHttpModule??
  • ????{??
  • ????????//?摘要:???
  • ????????//?????處置由實(shí)現(xiàn)?System.Web.IHttpModule?的模塊使用的資源(內(nèi)存除外)。??
  • ????????void?Dispose();??
  • ????????//??
  • ????????//?摘要:???
  • ????????//?????初始化模塊,并使其為處理請(qǐng)求做好準(zhǔn)備。??
  • ????????//??
  • ????????//?參數(shù):???
  • ????????//??context:??
  • ????????//??一個(gè)?System.Web.HttpApplication,它提供對(duì)?ASP.NET?應(yīng)用程序內(nèi)所有應(yīng)用程序?qū)ο蟮墓玫姆椒ā傩院褪录脑L問(wèn)??
  • ????????void?Init(HttpApplication?context);??
  • ????}??
  • 下面實(shí)現(xiàn)一個(gè)HttpModule,并訂閱管道中的一系列事件,訂閱事件就是在Init方法中綁定EventHandler的過(guò)程:

    代碼有點(diǎn)長(zhǎng),因?yàn)槲野衙恳粋€(gè)事件都訂閱了,這樣一來(lái)可以清楚的看出哪些事件執(zhí)行了,這些事件執(zhí)行的先后順序是什么。代碼如下:

  • public?class?MyModule?:?IHttpModule??
  • ????{??
  • ????????#region?IHttpModule?Members??
  • ??
  • ????????public?void?Dispose()??
  • ????????{??
  • ????????????//此處放置清除代碼。??
  • ????????}??
  • ??
  • ????????public?void?Init(HttpApplication?context)??
  • ????????{??
  • ????????????//?下面是如何處理?LogRequest?事件并為其???
  • ????????????//?提供自定義日志記錄實(shí)現(xiàn)的示例??
  • ????????????context.LogRequest?+=?new?EventHandler(OnLogRequest);??
  • ????????????context.BeginRequest?+=?new?EventHandler(context_BeginRequest);??
  • ????????????context.AuthenticateRequest?+=?new?EventHandler(context_AuthenticateRequest);??
  • ????????????context.AcquireRequestState?+=?new?EventHandler(context_AcquireRequestState);??
  • ????????????context.AuthorizeRequest?+=?new?EventHandler(context_AuthorizeRequest);??
  • ????????????context.Disposed?+=?new?EventHandler(context_Disposed);??
  • ????????????context.Error?+=?new?EventHandler(context_Error);??
  • ????????????context.EndRequest?+=?new?EventHandler(context_EndRequest);??
  • ????????????context.MapRequestHandler?+=?new?EventHandler(context_MapRequestHandler);??
  • ????????????context.PostAcquireRequestState?+=?new?EventHandler(context_PostAcquireRequestState);??
  • ????????????context.PostAuthenticateRequest?+=?new?EventHandler(context_PostAuthenticateRequest);??
  • ????????????context.PostAuthorizeRequest?+=?new?EventHandler(context_PostAuthorizeRequest);??
  • ????????????context.PostLogRequest?+=?new?EventHandler(context_PostLogRequest);??
  • ????????????context.PostReleaseRequestState?+=?new?EventHandler(context_PostReleaseRequestState);??
  • ????????????context.PostRequestHandlerExecute?+=?new?EventHandler(context_PostRequestHandlerExecute);??
  • ????????????context.PostResolveRequestCache?+=?new?EventHandler(context_PostResolveRequestCache);??
  • ????????????context.PostUpdateRequestCache?+=?new?EventHandler(context_PostUpdateRequestCache);??
  • ????????????context.ReleaseRequestState?+=?new?EventHandler(context_ReleaseRequestState);??
  • ????????????context.RequestCompleted?+=?new?EventHandler(context_RequestCompleted);??
  • ????????????context.ResolveRequestCache?+=?new?EventHandler(context_ResolveRequestCache);??
  • ????????????context.UpdateRequestCache?+=?new?EventHandler(context_UpdateRequestCache);??
  • ????????????context.PreRequestHandlerExecute?+=?new?EventHandler(context_PreRequestHandlerExecute);??
  • ????????????context.PreSendRequestContent?+=?new?EventHandler(context_PreSendRequestContent);??
  • ????????????context.PreSendRequestHeaders?+=?new?EventHandler(context_PreSendRequestHeaders);??
  • ????????????context.PostMapRequestHandler?+=?new?EventHandler(context_PostMapRequestHandler);??
  • ??
  • ??
  • ????????}??
  • ??
  • ????????void?context_Error(object?sender,?EventArgs?e)??
  • ????????{??
  • ????????????WriteLog("Error");??
  • ????????????//HttpContext.Current.Response.Write("Error<br?/>");??
  • ????????}??
  • ??
  • ????????void?context_UpdateRequestCache(object?sender,?EventArgs?e)??
  • ????????{??
  • ????????????WriteLog("UpdateRequestCache");??
  • ????????????//HttpContext.Current.Response.Write("UpdateRequestCache<br?/>");??
  • ????????}??
  • ??
  • ????????void?context_ResolveRequestCache(object?sender,?EventArgs?e)??
  • ????????{??
  • ????????????WriteLog("ResolveRequestCache");??
  • ????????????//?HttpContext.Current.Response.Write("ResolveRequestCache<br?/>");??
  • ????????}??
  • ??
  • ????????void?context_RequestCompleted(object?sender,?EventArgs?e)??
  • ????????{??
  • ????????????WriteLog("RequestCompleted");??
  • ????????????//?HttpContext.Current.Response.Write("RequestCompleted<br?/>");??
  • ????????}??
  • ??
  • ????????void?context_ReleaseRequestState(object?sender,?EventArgs?e)??
  • ????????{??
  • ????????????WriteLog("ReleaseRequestState");??
  • ????????????//HttpContext.Current.Response.Write("ReleaseRequestState<br?/>");??
  • ????????}??
  • ??
  • ????????void?context_PostUpdateRequestCache(object?sender,?EventArgs?e)??
  • ????????{??
  • ????????????WriteLog("PostUpdateRequestCache");??
  • ????????????//HttpContext.Current.Response.Write("PostUpdateRequestCache<br?/>");??
  • ????????}??
  • ??
  • ????????void?context_PostResolveRequestCache(object?sender,?EventArgs?e)??
  • ????????{??
  • ????????????WriteLog("PostResolveRequestCache");??
  • ????????????//HttpContext.Current.Response.Write("PostResolveRequestCache<br?/>");??
  • ????????}??
  • ??
  • ????????void?context_PostRequestHandlerExecute(object?sender,?EventArgs?e)??
  • ????????{??
  • ????????????WriteLog("PostRequestHandlerExecute");??
  • ????????????//HttpContext.Current.Response.Write("PostRequestHandlerExecute<br?/>");??
  • ????????}??
  • ??
  • ????????void?context_PostReleaseRequestState(object?sender,?EventArgs?e)??
  • ????????{??
  • ????????????WriteLog("PostReleaseRequestState");??
  • ????????????//HttpContext.Current.Response.Write("PostReleaseRequestState<br?/>");??
  • ????????}??
  • ??
  • ????????void?context_PostLogRequest(object?sender,?EventArgs?e)??
  • ????????{??
  • ????????????WriteLog("PostLogRequest");??
  • ????????????//HttpContext.Current.Response.Write("PostLogRequest<br?/>");??
  • ????????}??
  • ??
  • ????????void?context_PostAuthorizeRequest(object?sender,?EventArgs?e)??
  • ????????{??
  • ????????????WriteLog("PostAuthorizeRequest");??
  • ????????????//HttpContext.Current.Response.Write("PostAuthorizeRequest<br?/>");??
  • ????????}??
  • ??
  • ????????void?context_PostAuthenticateRequest(object?sender,?EventArgs?e)??
  • ????????{??
  • ????????????WriteLog("PostAuthenticateRequest");??
  • ????????????//HttpContext.Current.Response.Write("PostAuthenticateRequest<br?/>");??
  • ????????}??
  • ??
  • ????????void?context_PostAcquireRequestState(object?sender,?EventArgs?e)??
  • ????????{??
  • ????????????WriteLog("PostAcquireRequestState");??
  • ????????????//HttpContext.Current.Response.Write("PostAcquireRequestState<br?/>");??
  • ????????}??
  • ??
  • ????????void?context_MapRequestHandler(object?sender,?EventArgs?e)??
  • ????????{??
  • ????????????WriteLog("MapRequestHandler");??
  • ????????????//HttpContext.Current.Response.Write("MapRequestHandler<br?/>");??
  • ????????}??
  • ??
  • ????????void?context_Disposed(object?sender,?EventArgs?e)??
  • ????????{??
  • ????????????WriteLog("Disposed");??
  • ????????????//HttpContext.Current.Response.Write("Disposed<br?/>");??
  • ????????}??
  • ??
  • ????????void?context_AuthorizeRequest(object?sender,?EventArgs?e)??
  • ????????{??
  • ????????????WriteLog("AuthorizeRequest");??
  • ????????????//HttpContext.Current.Response.Write("AuthorizeRequest<br?/>");??
  • ????????}??
  • ??
  • ????????void?context_AcquireRequestState(object?sender,?EventArgs?e)??
  • ????????{??
  • ????????????WriteLog("AcquireRequestState");??
  • ????????????//HttpContext.Current.Response.Write("AcquireRequestState<br?/>");??
  • ????????}??
  • ??
  • ??
  • ????????void?context_PreSendRequestHeaders(object?sender,?EventArgs?e)??
  • ????????{??
  • ????????????WriteLog("PreSendRequestHeaders");??
  • ????????????//HttpContext.Current.Response.Write("PreSendRequestHeaders<br?/>");??
  • ????????}??
  • ??
  • ????????void?context_PreSendRequestContent(object?sender,?EventArgs?e)??
  • ????????{??
  • ????????????WriteLog("PreSendRequestContent");??
  • ????????????//HttpContext.Current.Response.Write("PreSendRequestContent<br?/>");??
  • ????????}??
  • ??
  • ????????void?context_PreRequestHandlerExecute(object?sender,?EventArgs?e)??
  • ????????{??
  • ????????????WriteLog("PreRequestHandlerExecute");??
  • ????????????//HttpContext.Current.Response.Write("PreRequestHandlerExecute<br?/>");??
  • ????????}??
  • ??
  • ????????void?context_EndRequest(object?sender,?EventArgs?e)??
  • ????????{??
  • ????????????WriteLog("EndRequest");??
  • ????????????//HttpContext.Current.Response.Write("EndRequest<br?/>");??
  • ????????}??
  • ??
  • ????????void?context_BeginRequest(object?sender,?EventArgs?e)??
  • ????????{??
  • ????????????WriteLog("*******************************************************************************");??
  • ????????????HttpApplication?app?=?sender?as?HttpApplication;??
  • ????????????WriteLog(app.Context.Request.Path);??
  • ????????????WriteLog("BeginRequest");??
  • ????????????//HttpContext.Current.Response.Write("BeginRequest<br?/>");??
  • ????????}??
  • ??
  • ????????void?context_AuthenticateRequest(object?sender,?EventArgs?e)??
  • ????????{??
  • ????????????WriteLog("AuthenticateRequest");??
  • ????????????//HttpContext.Current.Response.Write("AuthenticateRequest<br?/>");??
  • ????????}??
  • ????????#endregion??
  • ??
  • ????????public?void?OnLogRequest(Object?source,?EventArgs?e)??
  • ????????{??
  • ????????????//可以在此處放置自定義日志記錄邏輯??
  • ????????????WriteLog("OnLogRequest");??
  • ????????????//HttpContext.Current.Response.Write("OnLogRequest<br?/>");??
  • ????????}??
  • ??
  • ????????public?void?context_PostMapRequestHandler(object?sender,?EventArgs?e)??
  • ????????{??
  • ????????????WriteLog("PostMapRequestHandler");??
  • ????????????//HttpContext.Current.Response.Write("PostMapRequestHandler<br?/>");??
  • ????????}??
  • ??
  • ????????public?void?WriteLog(string?message)??
  • ????????{??
  • ????????????string?path?=?@"d:\aspnet\httpmodule.txt";??
  • ????????????StreamWriter?writer?=?null;??
  • ????????????if?(!File.Exists(path))??
  • ????????????{??
  • ????????????????writer?=?File.CreateText(path);??
  • ????????????}??
  • ????????????else??
  • ????????????{??
  • ????????????????FileInfo?info?=?new?FileInfo(path);??
  • ????????????????writer?=?info.AppendText();??
  • ??
  • ????????????}??
  • ????????????writer.WriteLine(message);??
  • ??
  • ????????????writer.Flush();??
  • ????????????writer.Close();??
  • ????????}??
  • ????}??
  • 訂閱的事件實(shí)現(xiàn)中,將事件名稱保存到我本地D盤的一個(gè)文本文件中。

    代碼實(shí)現(xiàn)完畢了,下一步就是要代碼起作用了,很簡(jiǎn)單,只需要在web.config中簡(jiǎn)單配置就可以了。配置中注意IIS7集成模式和IIS7經(jīng)典模式(包括IIS6)的區(qū)別,配置如下:

  • <!--IIS6或者IIS7經(jīng)典模式-->??
  • <system.web>??
  • ????<httpModules>??
  • ??????<add?name="mycustommodule"?type="fengzheng.MyModule,handler_modules"/>??
  • ????</httpModules>??
  • ??</system.web>??
  • <!--IIS7集成模式-->??
  • <system.webServer>??
  • ????<modules>??
  • ??????<add?name="mycustommodule"?type="fengzheng.MyModule,handler_modules"/>??
  • ????</modules>??
  • </system.webServer>??
  • 如此一來(lái),一個(gè)HttpModule及其配置工作就完成了,接下來(lái),發(fā)布網(wǎng)站到IIS或者直接在VS中運(yùn)行,隨便訪問(wèn)項(xiàng)目中的一個(gè)文件(任何文件類型都可以),我的項(xiàng)目中有一個(gè)WebForm2.aspx的頁(yè)面,我在瀏覽器中訪問(wèn)這個(gè)頁(yè)面,發(fā)現(xiàn)頁(yè)面是空白的,因?yàn)轫?yè)面中我什么都沒寫,上面的Module實(shí)現(xiàn)中,我把輸出全部放到本地D盤的一個(gè)文本文件中了,ok,打開那個(gè)文本文件。如圖:

    我們看到輸出內(nèi)容,第2行是訪問(wèn)的頁(yè)面地址,下面依次為訂閱的事件輸出,我們清楚的看到了事件的執(zhí)行順序。

  • BeginRequest????????????????#發(fā)出信號(hào)表示創(chuàng)建任何給定的新請(qǐng)求。?此事件始終被引發(fā),并且始終是請(qǐng)求處理期間發(fā)生的第一個(gè)事件??
  • AuthenticateRequest?????????#發(fā)出信號(hào)表示配置的身份驗(yàn)證機(jī)制已對(duì)當(dāng)前請(qǐng)求進(jìn)行了身份驗(yàn)證。?訂閱?AuthenticateRequest?事件可確保在處理附加模塊或事件處理程序之前對(duì)請(qǐng)求進(jìn)行身份驗(yàn)證??
  • PostAuthenticateRequest?????#預(yù)訂?PostAuthenticateRequest?事件的功能可以訪問(wèn)由?PostAuthenticateRequest?處理的任何數(shù)據(jù)??
  • AuthorizeRequest????????????#發(fā)出信號(hào)表示?ASP.NET?已對(duì)當(dāng)前請(qǐng)求進(jìn)行了授權(quán)。?訂閱?AuthorizeRequest?事件可確保在處理附加的模塊或事件處理程序之前對(duì)請(qǐng)求進(jìn)行身份驗(yàn)證和授權(quán)??
  • PostAuthorizeRequest????????#發(fā)出信號(hào)表示?ASP.NET?已對(duì)當(dāng)前請(qǐng)求進(jìn)行了授權(quán)。?訂閱?PostAuthorizeRequest?事件可確保在處理附加的模塊或處理程序之前對(duì)請(qǐng)求進(jìn)行身份驗(yàn)證和授權(quán)??
  • ResolveRequestCache?????????#引發(fā)這個(gè)事件來(lái)決定是否可以使用從輸出緩沖返回的內(nèi)容來(lái)結(jié)束請(qǐng)求。這依賴于Web應(yīng)用程序的輸出緩沖時(shí)怎樣設(shè)置的??
  • PostResolveRequestCache?????#在?ASP.NET?跳過(guò)當(dāng)前事件處理程序的執(zhí)行并允許緩存模塊滿足來(lái)自緩存的請(qǐng)求時(shí)發(fā)生??
  • MapRequestHandler???????????#ASP.NET?基礎(chǔ)結(jié)構(gòu)使用?MapRequestHandler?事件來(lái)確定用于當(dāng)前請(qǐng)求的請(qǐng)求處理程序??
  • PostMapRequestHandler???????#在?ASP.NET?已將當(dāng)前請(qǐng)求映射到相應(yīng)的事件處理程序時(shí)發(fā)生??
  • AcquireRequestState?????????#當(dāng)?ASP.NET?獲取與當(dāng)前請(qǐng)求關(guān)聯(lián)的當(dāng)前狀態(tài)(如會(huì)話狀態(tài))時(shí)發(fā)生??
  • PostAcquireRequestState?????#預(yù)訂?AcquireRequestState?事件的功能可以訪問(wèn)由?PostAcquireRequestState?處理的任何數(shù)據(jù)??
  • PreRequestHandlerExecute????#在ASP.NET開始執(zhí)行HTTP請(qǐng)求的處理程序之前引發(fā)這個(gè)事件。在這個(gè)事件之后,ASP.NET?把該請(qǐng)求轉(zhuǎn)發(fā)給適當(dāng)?shù)腍TTP處理程序??
  • PostRequestHandlerExecute???#在?ASP.NET?事件處理程序(例如,某頁(yè)或某個(gè)?XML?Web?service)執(zhí)行完畢時(shí)發(fā)生??
  • ReleaseRequestState?????????#在?ASP.NET?執(zhí)行完所有請(qǐng)求事件處理程序后發(fā)生。?該事件將使?fàn)顟B(tài)模塊保存當(dāng)前狀態(tài)數(shù)據(jù)??
  • PostReleaseRequestState?????#在?ASP.NET?已完成所有請(qǐng)求事件處理程序的執(zhí)行并且請(qǐng)求狀態(tài)數(shù)據(jù)已存儲(chǔ)時(shí)發(fā)生??
  • UpdateRequestCache??????????#當(dāng)?ASP.NET?執(zhí)行完事件處理程序以使緩存模塊存儲(chǔ)將用于從緩存為后續(xù)請(qǐng)求提供服務(wù)的響應(yīng)時(shí)發(fā)生??
  • PostUpdateRequestCache??????#在?ASP.NET?完成緩存模塊的更新并存儲(chǔ)了用于從緩存中為后續(xù)請(qǐng)求提供服務(wù)的響應(yīng)后,發(fā)生此事件??
  • OnLogRequest????????????????#恰好在?ASP.NET?為當(dāng)前請(qǐng)求執(zhí)行任何記錄之前發(fā)生,即使發(fā)生錯(cuò)誤,也會(huì)引發(fā)?LogRequest?事件??
  • PostLogRequest??????????????#在?ASP.NET?處理完?LogRequest?事件的所有事件處理程序后發(fā)生??
  • EndRequest??????????????????#在?ASP.NET?響應(yīng)請(qǐng)求時(shí)作為?HTTP?執(zhí)行管線鏈中的最后一個(gè)事件發(fā)生??
  • PreSendRequestContent???????#恰好在?ASP.NET?向客戶端發(fā)送內(nèi)容之前發(fā)生,可能發(fā)生多次??
  • PreSendRequestHeaders???????#恰好在?ASP.NET?向客戶端發(fā)送?HTTP?標(biāo)頭之前發(fā)生??
  • RequestCompleted????????????#在任何托管模塊和處理程序執(zhí)行后,它使模塊清理資源??
  • 訪問(wèn)一個(gè)頁(yè)面的過(guò)程中,依次觸發(fā)了23個(gè)事件,而HttpModule可訂閱的事件個(gè)數(shù)為25個(gè),觀察發(fā)現(xiàn),Error和Disposed這兩個(gè)事件沒有觸發(fā)。Error事件在發(fā)生錯(cuò)誤的情況下執(zhí)行,而Disposed事件,當(dāng)我們關(guān)閉剛才打開的頁(yè)面,再到文本文件里查看,發(fā)現(xiàn)Disposed事件出現(xiàn)了,所以Disposed在會(huì)話結(jié)束后觸發(fā)。

    由于HttpModule的個(gè)數(shù)可以有多個(gè),我們可以按照上面的方式定義HttpModule實(shí)現(xiàn)類,然后再web.config中增加配置項(xiàng),就可以實(shí)現(xiàn)多個(gè)HttpModule同時(shí)訂閱管道事件了。

    介紹完HttpModule,那么HttpHandler又是什么呢,它又在什么什么時(shí)候執(zhí)行呢?接下來(lái)看一下HttpHandler。

    HttpHandler

    HttpHandler是HTTP請(qǐng)求的處理中心,真正地對(duì)客戶端請(qǐng)求的服務(wù)器頁(yè)面做出編譯和執(zhí)行,并將處理過(guò)后的信息附加在HTTP請(qǐng)求信息流中再次返回到HttpModule中。??
    HttpHandler與HttpModule不同,一旦定義了自己的HttpHandler類,那么它對(duì)系統(tǒng)的HttpHandler的關(guān)系將是“覆蓋”關(guān)系。

    HttpHandler是實(shí)IHttpHandler接口的類,IHttpHandler接口定義如下:

  • public?interface?IHttpHandler??
  • {??
  • ????//?摘要:???
  • ????//?????獲取一個(gè)值,該值指示其他請(qǐng)求是否可以使用?System.Web.IHttpHandler?實(shí)例。??
  • ????//??
  • ????//?返回結(jié)果:???
  • ????//?????如果?System.Web.IHttpHandler?實(shí)例可再次使用,則為?true;否則為?false。??
  • ????bool?IsReusable?{?get;?}??
  • ??
  • ????//?摘要:???
  • ????//?????通過(guò)實(shí)現(xiàn)?System.Web.IHttpHandler?接口的自定義?HttpHandler?啟用?HTTP?Web?請(qǐng)求的處理。??
  • ????//??
  • ????//?參數(shù):???
  • ????//???context:??
  • ????//?????System.Web.HttpContext?對(duì)象,它提供對(duì)用于為?HTTP?請(qǐng)求提供服務(wù)的內(nèi)部服務(wù)器對(duì)象(如?Request、Response、Session??
  • ????//?????和?Server)的引用。??
  • ????void?ProcessRequest(HttpContext?context);??
  • }??
  • 接口中只有一個(gè)屬性和一個(gè)方法,所以實(shí)現(xiàn)一個(gè)HttpHandler也很簡(jiǎn)單,下面實(shí)現(xiàn)一個(gè)簡(jiǎn)單的HttpHandler,代碼如下:

  • public?class?MyIISHandler?:?IHttpHandler??
  • ????{??
  • ????????///?<summary>??
  • ????????///?您將需要在網(wǎng)站的?Web.config?文件中配置此處理程序???
  • ????????///?并向?IIS?注冊(cè)它,然后才能使用它。有關(guān)詳細(xì)信息,??
  • ????????///?請(qǐng)參見下面的鏈接:?http://go.microsoft.com/?linkid=8101007??
  • ????????///?</summary>??
  • ????????#region?IHttpHandler?Members??
  • ??
  • ????????public?bool?IsReusable??
  • ????????{??
  • ????????????//?如果無(wú)法為其他請(qǐng)求重用托管處理程序,則返回?false。??
  • ????????????//?如果按請(qǐng)求保留某些狀態(tài)信息,則通常這將為?false。??
  • ????????????get?{?return?true;?}??
  • ????????}??
  • ??
  • ????????public?void?ProcessRequest(HttpContext?context)??
  • ????????{??
  • ????????????//在此處寫入您的處理程序?qū)崿F(xiàn)。??
  • ????????????WriteLog("請(qǐng)求一個(gè)asox頁(yè)面");??
  • ????????}??
  • ??
  • ????????#endregion??
  • ????}??
  • 上面我實(shí)現(xiàn)了一個(gè)很簡(jiǎn)單的HttpHandler類,在ProcessRequest方法中,調(diào)用上面的HttpModule類中寫文本文件的方法,在文本文件中寫入“請(qǐng)求一個(gè)asox頁(yè)面”,沒錯(cuò),是一個(gè)asox頁(yè)面,我自己定義的文件格式,下面我會(huì)在web.config中添加配置項(xiàng):

  • <!--IIS6或者IIS7經(jīng)典模式-->??
  • ??<system.web>??
  • ????<httpHandlers>??
  • ??????<add?name="mycustomhandler"?path="*.asox"?verb="*"?type="fengzheng.MyIISHandler,handler_modules"/>??
  • ????</httpHandlers>??
  • ??</system.web>??
  • ???
  • <!--IIS7集成模式-->??
  • ??<system.webServer>??
  • ????<handlers>??
  • ???????<add?name="mycustomhandler"?path="*.asox"?verb="*"?type="fengzheng.MyIISHandler,handler_modules"/>??
  • ????</handlers>??
  • ??</system.webServer>??
  • 配置項(xiàng)屬性的解釋:

    path:指定了需要調(diào)用處理程序的路徑和文件名(可以包含通配符)。“*”、“*.aspx”、“booklist.aspx”、“test1.aspx,test2.aspx”、“*.asox”、“*.txt”。

    verb:指定了處理程序支持的HTTP動(dòng)作。*-支持所有的HTTP動(dòng)作;“GET”-支持Get操作;“POST”-支持Post操作;“GET, POST”-支持兩種操作。

    type:用名字空間、類名稱和程序集名稱的組合形式指定處理程序或處理程序工廠的實(shí)際類型。ASP.NET運(yùn)行時(shí)首先搜索bin目錄中的DLL,接著在GAC中搜索。

    接著,發(fā)布站點(diǎn)到IIS。打開IIS,找到當(dāng)前站點(diǎn)的“處理程序映射”,會(huì)發(fā)現(xiàn)多了剛剛配置的HttpHandler,如圖:

    沒錯(cuò),關(guān)于對(duì)*.asox這種類型的文件,就可以映射到上面創(chuàng)建的HttpHandler來(lái)進(jìn)行處理,觀察其它條目發(fā)現(xiàn),像*.aspx、*.ashx的處理程序是System.Web.UI.PageHandlerFactory和System.Web.UI.SimpleHandlerFactory這樣的工廠類型。沒錯(cuò),可以指定處理程序?yàn)橐粋€(gè)HttpHandler,也可以指定為一個(gè)抽象工廠類型。先不說(shuō)工廠類型的事兒,訪問(wèn)一下網(wǎng)站中的asox頁(yè)面,看一下文本文件的記錄情況。

    起作用了,在HttpModule輸出的一堆信息中,夾雜著HttpHandler的輸出,當(dāng)然這僅限于訪問(wèn)asox類型的頁(yè)面,因?yàn)槲抑粚?duì)路徑為*.asox的文件格式做了設(shè)置,修改下配置文件,例如將path=”*.asox”改為path=”*.aspx”,那么ASP.NET對(duì)*.aspx頁(yè)面原有的解析機(jī)制將被我們?cè)O(shè)置的處理程序所覆蓋。

    回到上面的輸出內(nèi)容,我們觀察HttpHandler輸出內(nèi)容所在的位置,位于PreRequestHandlerExecute和PostRequestHandlerExecute這兩個(gè)事件之間,這與HttpApplication類中的管道事件的創(chuàng)建過(guò)程有關(guān)。

    前面說(shuō)到了,處理處理程序可以指定為一個(gè)工廠類型,下面,我就創(chuàng)建一個(gè)工廠類型的處理程序。

    這里所說(shuō)的工廠類型的處理程序,就是實(shí)現(xiàn)了IHttpHandlerFactory接口的類,IHttpHandlerFactory接口定義如下:

  • public?interface?IHttpHandlerFactory??
  • ????{??
  • ????????//?摘要:???
  • ????????//?????返回實(shí)現(xiàn)?System.Web.IHttpHandler?接口的類的實(shí)例。??
  • ????????//??
  • ????????//?參數(shù):???
  • ????????//???context:??
  • ????????//?????System.Web.HttpContext?類的實(shí)例,它提供對(duì)用于為?HTTP?請(qǐng)求提供服務(wù)的內(nèi)部服務(wù)器對(duì)象(如?Request、Response、Session??
  • ????????//?????和?Server)的引用。??
  • ????????//??
  • ????????//???requestType:??
  • ????????//?????客戶端使用的?HTTP?數(shù)據(jù)傳輸方法(GET?或?POST)。??
  • ????????//??
  • ????????//???url:??
  • ????????//?????所請(qǐng)求資源的?System.Web.HttpRequest.RawUrl。??
  • ????????//??
  • ????????//???pathTranslated:??
  • ????????//?????所請(qǐng)求資源的?System.Web.HttpRequest.PhysicalApplicationPath。??
  • ????????//??
  • ????????//?返回結(jié)果:???
  • ????????//?????處理請(qǐng)求的新的?System.Web.IHttpHandler?對(duì)象。??
  • ????????IHttpHandler?GetHandler(HttpContext?context,?string?requestType,?string?url,?string?pathTranslated);??
  • ????????//??
  • ????????//?摘要:???
  • ????????//?????使工廠可以重用現(xiàn)有的處理程序?qū)嵗?/span>??
  • ????????//??
  • ????????//?參數(shù):???
  • ????????//???handler:??
  • ????????//?????要重用的?System.Web.IHttpHandler?對(duì)象。??
  • ????????void?ReleaseHandler(IHttpHandler?handler);??
  • ????}??
  • 同樣很簡(jiǎn)單,也是只有兩個(gè)接口方法,下面是實(shí)現(xiàn)這個(gè)接口的工廠,代碼如下:

  • public?class?MyHttpHandlerFactory:IHttpHandlerFactory??
  • {??
  • ????????public?IHttpHandler?GetHandler(HttpContext?context,?string?requestType,?string?url,?string?pathTranslated)??
  • ????????{??
  • ????????????//寫日志??
  • ????????????WriteLog(string.Format("requestType:{0}|url:{1}|pathTranslated:{2}",?requestType,?url,?pathTranslated));??
  • ??????????????
  • ????????????//生成一個(gè)IHttpHandler??
  • ????????????Type?t?=?typeof(MyIISHandler);??
  • ????????????IHttpHandler?handler?=??Activator.CreateInstance(t)?as?IHttpHandler;??
  • ????????????return?handler;??
  • ????????}??
  • ??
  • ????????public?void?ReleaseHandler(IHttpHandler?handler)??
  • ????????{??
  • ????????}??
  • }??
  • 方法中,返回了前面創(chuàng)建的那個(gè)HttpHander類,依然調(diào)用記錄文本文件的方法輸出內(nèi)容,方便觀察執(zhí)行的實(shí)際和具體內(nèi)容。配置文件改改為這個(gè)工廠類。

  • <add?name="mycustomFactoryHandler"?path="*.asox"?verb="*"?type="fengzheng.MyHttpHandlerFactory,handler_modules"/>??
  • 配置完畢后,訪問(wèn)網(wǎng)站中的asox頁(yè)面,打開文本文件,內(nèi)容如下:

    我們發(fā)現(xiàn),工廠類中構(gòu)造IHttpHandler接口的方法發(fā)生在HttpModule的MapRequestHandler之后,這同樣與HttpApplication類中構(gòu)造管道事件有關(guān)。

    說(shuō)了這么多,那么,HttpModule和HttpHandler究竟能干什么呢?

    HttpModule很常用的一個(gè)作用就是Url重寫,URLRewriter就是基于HttpModule實(shí)現(xiàn)的。

    另外,有通過(guò)HttpHandler對(duì)圖片加水印,防止盜鏈的。

    具體的可以參考這篇文章

    部署網(wǎng)站注意事項(xiàng):

    網(wǎng)站采用.net 4.0集成模式部署,集成模式是一種統(tǒng)一的請(qǐng)求處理管道,它將ASP.NET請(qǐng)求管道與IIS核心管道組合在一起,這種模式能夠提供更好的性能,能夠?qū)崿F(xiàn)配置和治理的模塊化,而且增加了使用托管代碼模塊擴(kuò)展IIS時(shí)的靈活性。IIS經(jīng)典模式與集成模式的區(qū)別

    集成模式和經(jīng)典模式的配置文件稍有不同,部署時(shí)需要注意針對(duì)不同的部署模式,修改配置文件。在vs2013中新建的web應(yīng)用程序,默認(rèn)的web.config內(nèi)容如下:

  • <?xml?version="1.0"?encoding="utf-8"?>??
  • <!--??
  • ??有關(guān)如何配置?ASP.NET?應(yīng)用程序的詳細(xì)信息,請(qǐng)?jiān)L問(wèn)??
  • ??http://go.microsoft.com/fwlink/?LinkId=169433??
  • ??-->??
  • <configuration>??
  • ??<system.web>??
  • ????<compilation?debug="true"?targetFramework="4.5"?/>??
  • ????<httpRuntime?targetFramework="4.5"?/>??
  • ??</system.web>??
  • </configuration>??
    • 按照經(jīng)典模式部署,配置文件應(yīng)該如下:
  • <?xml?version="1.0"?encoding="utf-8"?>??
  • <!--??
  • ??有關(guān)如何配置?ASP.NET?應(yīng)用程序的詳細(xì)信息,請(qǐng)?jiān)L問(wèn)??
  • ??http://go.microsoft.com/fwlink/?LinkId=169433??
  • ??-->??
  • <configuration>??
  • ??<system.web>??
  • ????<compilation?debug="true"?targetFramework="4.5"?/>??
  • ????<httpRuntime?targetFramework="4.5"?/>??
  • ????<httpModules>??
  • ??????<add?name="mycustommodule"?type="fengzheng.MyModule,handler_modules"/>??
  • ????</httpModules>??
  • ????<httpHandlers>??
  • ??????<add?name="mycustomhandler"?path="*.asox"?verb="*"?type="fengzheng.MyIISHandler,handler_modules"/>??
  • ????</httpHandlers>??
  • ??</system.web>??
  • </configuration>??
  • 經(jīng)典模式經(jīng)測(cè)試總是出現(xiàn)如下錯(cuò)誤,500.21 - 模塊無(wú)法識(shí)別:

  • HTTP?錯(cuò)誤?500.21?-?Internal?Server?Error??
  • 處理程序“PageHandlerFactory-ISAPI-4.0_64bit”在其模塊列表中有一個(gè)錯(cuò)誤模塊“IsapiModule”??
  • 至于錯(cuò)誤原因:目前還不是很清楚。

    • 按照集成模式部署,配置文件應(yīng)該如下,將配置信息放到system.webServer節(jié)點(diǎn)之下:
  • <?xml?version="1.0"?encoding="utf-8"?>??
  • <!--??
  • ??有關(guān)如何配置?ASP.NET?應(yīng)用程序的詳細(xì)信息,請(qǐng)?jiān)L問(wèn)??
  • ??http://go.microsoft.com/fwlink/?LinkId=169433??
  • ??-->??
  • <configuration>??
  • ??<system.web>??
  • ????<compilation?debug="true"?targetFramework="4.5"?/>??
  • ????<httpRuntime?targetFramework="4.5"?/>??
  • ??</system.web>??
  • ??<system.webServer>??
  • ????<modules>??
  • ??????<add?name="mycustommodule"?type="fengzheng.MyModule,handler_modules"/>??
  • ????</modules>??
  • ????<handlers>??
  • ??????<add?name="mycustomhandler"?path="*"?verb="*"?type="fengzheng.MyIISHandler,handler_modules"/>??
  • ????</handlers>??
  • ??</system.webServer>??
  • </configuration>??
  • 總結(jié)

    以上是生活随笔為你收集整理的ASP.NET-自定义HttpModule与HttpHandler的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。