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 文野
-
博客地址:http://www.cnblogs.com/wolf-sun/
博客版权:如果文中有不妥或者错误的地方还望高手的你指出,以免误人子弟。如果觉得本文对你有所帮助不如【推荐】一下!如果你有更好的建议,不如留言一起讨论,共同进步! 再次感谢您耐心的读完本篇文章。