IHttpModule的那些事


寫在前面

關於IHttpModule的相關內容,在面試的時候也被問到過,當時也是隱隱約約的感覺這個接口有一個Init方法,可以在實現類中的Init方法注冊一系列的事件,說句實話,具體哪些事件,忘了差不多了。今天周末在家,也確實沒什么事,就算是對這塊知識進行查漏補缺了。

IHttpModule工作方式

熟悉asp.net生命周期的朋友,應該知道HttpModule的執行是在HttpHandler之前被執行,執行HttpModule的一系列事件后然后執行HttpHandler,然后又執行HttpModule的一些事件。具體的可以參考下面的生命周期的圖。

而HttpHandler才是處理http請求的地方,HttpModule是一個HTTP請求的“必經之路”,所以可以在這個HTTP請求傳遞到真正的請求處理中心(HttpHandler)之前附加一些需要的信息在這個HTTP請求信息之上,或者針對截獲的這個HTTP請求信息作一些額外的工作,或者在某些情況下干脆終止滿足一些條件的HTTP請求,從而可以起到一個Filter過濾器的作用。

一個HTTP請求在HttpModule容器的傳遞過程中,會在某一時刻(ResolveRequestCache事件)將這個HTTP請求傳遞給HttpHandler容器。在這個事件之后,HttpModule容器會建立一個HttpHandler的入口實例,但是此時並沒有將HTTP請求控制權交出,而是繼續觸發AcquireRequestState事件以及PreRequestHandlerExcute事件。在PreRequestHandlerExcute事件之后,HttpModule窗口就會將控制權暫時交給HttpHandler容器,以便進行真正的HTTP請求處理工作。

而在HttpHandler容器內部會執行ProcessRequest方法來處理HTTP請求。在容器HttpHandler處理完畢整個HTTP請求之后,會將控制權交還給HttpModule,HttpModule則會繼續對處理完畢的HTTP請求信息流進行層層的轉交動作,直到返回到客戶端為止。

一個實例

項目結構

MyHttpModule代碼

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 
 6 namespace MyHttpModule
 7 {
 8     /// <summary>
 9     /// 自定義HttpModule
10     /// </summary>
11     public class MyHttpModule : IHttpModule
12     {
13         public void Dispose()
14         {
15             throw new NotImplementedException();
16         }
17 
18         public void Init(HttpApplication context)
19         {
20             context.BeginRequest += context_BeginRequest;
21             context.EndRequest += context_EndRequest;
22         }
23 
24         void context_EndRequest(object sender, EventArgs e)
25         {
26             HttpApplication app = sender as HttpApplication;
27             if (app != null)
28             {
29                 HttpContext context = app.Context;
30                 HttpResponse response = app.Response;
31                 response.Write("自定義HttpModule中的EndRequest");
32 
33             }
34         }
35 
36         void context_BeginRequest(object sender, EventArgs e)
37         {
38             HttpApplication app = sender as HttpApplication;
39             if (app != null)
40             {
41                 HttpContext context = app.Context;
42                 HttpResponse response = app.Response;
43                 response.Write("自定義HttpModule中的BeginRequest");
44 
45             }
46         }
47     }
48 }

在web.config注冊自定義的HttpModule

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <!--
 3   For more information on how to configure your ASP.NET application, please visit
 4   http://go.microsoft.com/fwlink/?LinkId=169433
 5   -->
 6 <configuration>
 7   <system.web>
 8     <compilation debug="true" targetFramework="4.5" />
 9     <httpRuntime targetFramework="4.5" />
10    
11   </system.web>
12   <system.webServer>
13     <modules>
14       <add name="MyHttpModule" type="MyHttpModule.MyHttpModule,MyHttpModule"/>
15     </modules>
16   </system.webServer>
17 </configuration>

瀏覽頁面Default.aspx

那么在生命周期過程中的一系列的事件的執行順序是怎樣的呢?

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Web;
  5 
  6 namespace MyHttpModule
  7 {
  8     /// <summary>
  9     /// 自定義HttpModule
 10     /// </summary>
 11     public class MyHttpModule : IHttpModule
 12     {
 13         public void Dispose()
 14         {
 15             throw new NotImplementedException();
 16         }
 17 
 18         public void Init(HttpApplication context)
 19         {
 20             context.BeginRequest += context_BeginRequest;
 21             context.EndRequest += context_EndRequest;
 22             context.PostAcquireRequestState += context_PostAcquireRequestState;
 23             context.PostAuthenticateRequest += context_PostAuthenticateRequest;
 24             context.PostAuthorizeRequest += context_PostAuthorizeRequest;
 25             context.PostLogRequest += context_PostLogRequest;
 26             context.PostMapRequestHandler += context_PostMapRequestHandler;
 27             context.PostRequestHandlerExecute += context_PostRequestHandlerExecute;
 28             context.PostResolveRequestCache += context_PostResolveRequestCache;
 29             context.PostUpdateRequestCache += context_PostUpdateRequestCache;
 30             context.PreRequestHandlerExecute += context_PreRequestHandlerExecute;
 31             context.PreSendRequestContent += context_PreSendRequestContent;
 32             context.PreSendRequestHeaders += context_PreSendRequestHeaders;
 33             context.RequestCompleted += context_RequestCompleted;
 34             context.ResolveRequestCache += context_ResolveRequestCache;
 35             context.UpdateRequestCache += context_UpdateRequestCache;
 36             context.ReleaseRequestState += context_ReleaseRequestState;
 37         }
 38 
 39         void context_UpdateRequestCache(object sender, EventArgs e)
 40         {
 41             HttpApplication app = sender as HttpApplication;
 42             if (app != null)
 43             {
 44                 HttpContext context = app.Context;
 45                 HttpResponse response = app.Response;
 46                 response.Write("自定義HttpModule中的UpdateRequestCache<br/>");
 47             }
 48         }
 49 
 50         void context_ResolveRequestCache(object sender, EventArgs e)
 51         {
 52             HttpApplication app = sender as HttpApplication;
 53             if (app != null)
 54             {
 55                 HttpContext context = app.Context;
 56                 HttpResponse response = app.Response;
 57                 response.Write("自定義HttpModule中的ResolveRequestCache<br/>");
 58             }
 59         }
 60 
 61         void context_RequestCompleted(object sender, EventArgs e)
 62         {
 63             HttpApplication app = sender as HttpApplication;
 64             if (app != null)
 65             {
 66                 HttpContext context = app.Context;
 67                 HttpResponse response = app.Response;
 68                 response.Write("自定義HttpModule中的RequestCompleted<br/>");
 69             }
 70         }
 71 
 72         void context_PreSendRequestHeaders(object sender, EventArgs e)
 73         {
 74             HttpApplication app = sender as HttpApplication;
 75             if (app != null)
 76             {
 77                 HttpContext context = app.Context;
 78                 HttpResponse response = app.Response;
 79                 response.Write("自定義HttpModule中的PreSendRequestHeaders<br/>");
 80             }
 81         }
 82 
 83         void context_PreSendRequestContent(object sender, EventArgs e)
 84         {
 85             HttpApplication app = sender as HttpApplication;
 86             if (app != null)
 87             {
 88                 HttpContext context = app.Context;
 89                 HttpResponse response = app.Response;
 90                 response.Write("自定義HttpModule中的PreSendRequestContent<br/>");
 91             }
 92         }
 93 
 94         void context_PreRequestHandlerExecute(object sender, EventArgs e)
 95         {
 96             HttpApplication app = sender as HttpApplication;
 97             if (app != null)
 98             {
 99                 HttpContext context = app.Context;
100                 HttpResponse response = app.Response;
101                 response.Write("自定義HttpModule中的PreRequestHandlerExecute<br/>");
102             }
103         }
104 
105         void context_PostUpdateRequestCache(object sender, EventArgs e)
106         {
107             HttpApplication app = sender as HttpApplication;
108             if (app != null)
109             {
110                 HttpContext context = app.Context;
111                 HttpResponse response = app.Response;
112                 response.Write("自定義HttpModule中的PostUpdateRequestCache<br/>");
113             }
114         }
115 
116         void context_PostResolveRequestCache(object sender, EventArgs e)
117         {
118             HttpApplication app = sender as HttpApplication;
119             if (app != null)
120             {
121                 HttpContext context = app.Context;
122                 HttpResponse response = app.Response;
123                 response.Write("自定義HttpModule中的PostResolveRequestCache<br/>");
124             }
125         }
126 
127         void context_PostRequestHandlerExecute(object sender, EventArgs e)
128         {
129             HttpApplication app = sender as HttpApplication;
130             if (app != null)
131             {
132                 HttpContext context = app.Context;
133                 HttpResponse response = app.Response;
134                 response.Write("自定義HttpModule中的PostRequestHandlerExecut<br/>");
135             }
136         }
137 
138         void context_PostMapRequestHandler(object sender, EventArgs e)
139         {
140             HttpApplication app = sender as HttpApplication;
141             if (app != null)
142             {
143                 HttpContext context = app.Context;
144                 HttpResponse response = app.Response;
145                 response.Write("自定義HttpModule中的PostMapRequestHandler<br/>");
146             }
147         }
148 
149         void context_PostLogRequest(object sender, EventArgs e)
150         {
151               HttpApplication app = sender as HttpApplication;
152             if (app != null)
153             {
154                 HttpContext context = app.Context;
155                 HttpResponse response = app.Response;
156                 response.Write("自定義HttpModule中的PostLogRequest<br/>");
157             }
158         }
159 
160         void context_PostAuthorizeRequest(object sender, EventArgs e)
161         {
162             HttpApplication app = sender as HttpApplication;
163             if (app != null)
164             {
165                 HttpContext context = app.Context;
166                 HttpResponse response = app.Response;
167                 response.Write("自定義HttpModule中的PostAuthorizeRequest<br/>");
168             }
169         }
170 
171         void context_PostAuthenticateRequest(object sender, EventArgs e)
172         {
173             HttpApplication app = sender as HttpApplication;
174             if (app != null)
175             {
176                 HttpContext context = app.Context;
177                 HttpResponse response = app.Response;
178                 response.Write("自定義HttpModule中的PostAuthenticateRequest<br/>");
179             }
180         }
181 
182         void context_PostAcquireRequestState(object sender, EventArgs e)
183         {
184             HttpApplication app = sender as HttpApplication;
185             if (app != null)
186             {
187                 HttpContext context = app.Context;
188                 HttpResponse response = app.Response;
189                 response.Write("自定義HttpModule中的PostAcquireRequestState<br/>");
190             }
191         }
192 
193         void context_ReleaseRequestState(object sender, EventArgs e)
194         {
195             HttpApplication app = sender as HttpApplication;
196             if (app != null)
197             {
198                 HttpContext context = app.Context;
199                 HttpResponse response = app.Response;
200                 response.Write("自定義HttpModule中的ReleaseRequestState<br/>");
201             }
202         }
203 
204         void context_EndRequest(object sender, EventArgs e)
205         {
206             HttpApplication app = sender as HttpApplication;
207             if (app != null)
208             {
209                 HttpContext context = app.Context;
210                 HttpResponse response = app.Response;
211                 response.Write("自定義HttpModule中的EndRequest<br/>");
212             }
213         }
214 
215         void context_BeginRequest(object sender, EventArgs e)
216         {
217             HttpApplication app = sender as HttpApplication;
218             if (app != null)
219             {
220                 HttpContext context = app.Context;
221                 HttpResponse response = app.Response;
222                 response.Write("自定義HttpModule中的BeginRequest<br/>");
223 
224             }
225         }
226     }
227 }

 瀏覽結果

使用HttpModule終止此次Http請求

 

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Web;
 7 namespace MyHttpModule
 8 {
 9     public class EndModule : IHttpModule
10     {
11         public void Dispose()
12         {
13             throw new NotImplementedException();
14         }
15 
16         public void Init(HttpApplication context)
17         {
18             context.BeginRequest += context_BeginRequest;
19         }
20 
21         void context_BeginRequest(object sender, EventArgs e)
22         {
23             HttpApplication application = (HttpApplication)sender;
24 
25             application.CompleteRequest();
26 
27             application.Context.Response.Write("請求被終止。");
28 
29         }
30     }
31 }

結果

總結

這里介紹了在asp.net生命周期中一個最重要的接口IHttpModule,可以這樣來形容該接口,事件接口,因為在實現類中的Init方法中,可以注冊生命周期中的各種事件,並可以在事件中定義各種邏輯。

參考文章

一點一點學ASP.NET之基礎概念——HttpModule 文野

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM