日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

ASP.NET-自定义HttpModule与HttpHandler

發布時間:2024/9/20 asp.net 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ASP.NET-自定义HttpModule与HttpHandler 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在之前的ASP.NET是如何在IIS下工作的這篇文章中介紹了ASP.NET與IIS配合工作的機制,在http請求經過一系列處理后,最后到達ASP.NET管道中,這時,就是Http Modules和HttpHandler出場的時候了。

  再來擺出管道工作時序圖來一看:

HttpModule

HttpModule是類似于過濾器的作用,可以沒有,也可以有任意個,每一個都可以訂閱管道事件中的任意個事件,在每個訂閱的事件中可自定義功能實現。

HttpModule是實現IHttpModule接口的類。接口如下:

  • public?interface?IHttpModule??
  • ????{??
  • ????????//?摘要:???
  • ????????//?????處置由實現?System.Web.IHttpModule?的模塊使用的資源(內存除外)。??
  • ????????void?Dispose();??
  • ????????//??
  • ????????//?摘要:???
  • ????????//?????初始化模塊,并使其為處理請求做好準備。??
  • ????????//??
  • ????????//?參數:???
  • ????????//??context:??
  • ????????//??一個?System.Web.HttpApplication,它提供對?ASP.NET?應用程序內所有應用程序對象的公用的方法、屬性和事件的訪問??
  • ????????void?Init(HttpApplication?context);??
  • ????}??
  • 下面實現一個HttpModule,并訂閱管道中的一系列事件,訂閱事件就是在Init方法中綁定EventHandler的過程:

    代碼有點長,因為我把每一個事件都訂閱了,這樣一來可以清楚的看出哪些事件執行了,這些事件執行的先后順序是什么。代碼如下:

  • public?class?MyModule?:?IHttpModule??
  • ????{??
  • ????????#region?IHttpModule?Members??
  • ??
  • ????????public?void?Dispose()??
  • ????????{??
  • ????????????//此處放置清除代碼。??
  • ????????}??
  • ??
  • ????????public?void?Init(HttpApplication?context)??
  • ????????{??
  • ????????????//?下面是如何處理?LogRequest?事件并為其???
  • ????????????//?提供自定義日志記錄實現的示例??
  • ????????????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();??
  • ????????}??
  • ????}??
  • 訂閱的事件實現中,將事件名稱保存到我本地D盤的一個文本文件中。

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

  • <!--IIS6或者IIS7經典模式-->??
  • <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>??
  • 如此一來,一個HttpModule及其配置工作就完成了,接下來,發布網站到IIS或者直接在VS中運行,隨便訪問項目中的一個文件(任何文件類型都可以),我的項目中有一個WebForm2.aspx的頁面,我在瀏覽器中訪問這個頁面,發現頁面是空白的,因為頁面中我什么都沒寫,上面的Module實現中,我把輸出全部放到本地D盤的一個文本文件中了,ok,打開那個文本文件。如圖:

    我們看到輸出內容,第2行是訪問的頁面地址,下面依次為訂閱的事件輸出,我們清楚的看到了事件的執行順序。

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

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

    介紹完HttpModule,那么HttpHandler又是什么呢,它又在什么什么時候執行呢?接下來看一下HttpHandler。

    HttpHandler

    HttpHandler是HTTP請求的處理中心,真正地對客戶端請求的服務器頁面做出編譯和執行,并將處理過后的信息附加在HTTP請求信息流中再次返回到HttpModule中。??
    HttpHandler與HttpModule不同,一旦定義了自己的HttpHandler類,那么它對系統的HttpHandler的關系將是“覆蓋”關系。

    HttpHandler是實IHttpHandler接口的類,IHttpHandler接口定義如下:

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

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

  • <!--IIS6或者IIS7經典模式-->??
  • ??<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>??
  • 配置項屬性的解釋:

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

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

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

    接著,發布站點到IIS。打開IIS,找到當前站點的“處理程序映射”,會發現多了剛剛配置的HttpHandler,如圖:

    沒錯,關于對*.asox這種類型的文件,就可以映射到上面創建的HttpHandler來進行處理,觀察其它條目發現,像*.aspx、*.ashx的處理程序是System.Web.UI.PageHandlerFactory和System.Web.UI.SimpleHandlerFactory這樣的工廠類型。沒錯,可以指定處理程序為一個HttpHandler,也可以指定為一個抽象工廠類型。先不說工廠類型的事兒,訪問一下網站中的asox頁面,看一下文本文件的記錄情況。

    起作用了,在HttpModule輸出的一堆信息中,夾雜著HttpHandler的輸出,當然這僅限于訪問asox類型的頁面,因為我只對路徑為*.asox的文件格式做了設置,修改下配置文件,例如將path=”*.asox”改為path=”*.aspx”,那么ASP.NET對*.aspx頁面原有的解析機制將被我們設置的處理程序所覆蓋。

    回到上面的輸出內容,我們觀察HttpHandler輸出內容所在的位置,位于PreRequestHandlerExecute和PostRequestHandlerExecute這兩個事件之間,這與HttpApplication類中的管道事件的創建過程有關。

    前面說到了,處理處理程序可以指定為一個工廠類型,下面,我就創建一個工廠類型的處理程序。

    這里所說的工廠類型的處理程序,就是實現了IHttpHandlerFactory接口的類,IHttpHandlerFactory接口定義如下:

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

  • 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));??
  • ??????????????
  • ????????????//生成一個IHttpHandler??
  • ????????????Type?t?=?typeof(MyIISHandler);??
  • ????????????IHttpHandler?handler?=??Activator.CreateInstance(t)?as?IHttpHandler;??
  • ????????????return?handler;??
  • ????????}??
  • ??
  • ????????public?void?ReleaseHandler(IHttpHandler?handler)??
  • ????????{??
  • ????????}??
  • }??
  • 方法中,返回了前面創建的那個HttpHander類,依然調用記錄文本文件的方法輸出內容,方便觀察執行的實際和具體內容。配置文件改改為這個工廠類。

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

    我們發現,工廠類中構造IHttpHandler接口的方法發生在HttpModule的MapRequestHandler之后,這同樣與HttpApplication類中構造管道事件有關。

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

    HttpModule很常用的一個作用就是Url重寫,URLRewriter就是基于HttpModule實現的。

    另外,有通過HttpHandler對圖片加水印,防止盜鏈的。

    具體的可以參考這篇文章

    部署網站注意事項:

    網站采用.net 4.0集成模式部署,集成模式是一種統一的請求處理管道,它將ASP.NET請求管道與IIS核心管道組合在一起,這種模式能夠提供更好的性能,能夠實現配置和治理的模塊化,而且增加了使用托管代碼模塊擴展IIS時的靈活性。IIS經典模式與集成模式的區別

    集成模式和經典模式的配置文件稍有不同,部署時需要注意針對不同的部署模式,修改配置文件。在vs2013中新建的web應用程序,默認的web.config內容如下:

  • <?xml?version="1.0"?encoding="utf-8"?>??
  • <!--??
  • ??有關如何配置?ASP.NET?應用程序的詳細信息,請訪問??
  • ??http://go.microsoft.com/fwlink/?LinkId=169433??
  • ??-->??
  • <configuration>??
  • ??<system.web>??
  • ????<compilation?debug="true"?targetFramework="4.5"?/>??
  • ????<httpRuntime?targetFramework="4.5"?/>??
  • ??</system.web>??
  • </configuration>??
    • 按照經典模式部署,配置文件應該如下:
  • <?xml?version="1.0"?encoding="utf-8"?>??
  • <!--??
  • ??有關如何配置?ASP.NET?應用程序的詳細信息,請訪問??
  • ??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>??
  • 經典模式經測試總是出現如下錯誤,500.21 - 模塊無法識別:

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

    • 按照集成模式部署,配置文件應該如下,將配置信息放到system.webServer節點之下:
  • <?xml?version="1.0"?encoding="utf-8"?>??
  • <!--??
  • ??有關如何配置?ASP.NET?應用程序的詳細信息,請訪問??
  • ??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>??
  • 總結

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

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。