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 文野

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。