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代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace MyHttpModule
{
/// <summary>
/// 自定义HttpModule
/// </summary>
public class MyHttpModule : IHttpModule
{
public void Dispose()
{
throw new NotImplementedException();
} public void Init(HttpApplication context)
{
context.BeginRequest += context_BeginRequest;
context.EndRequest += context_EndRequest;
} void context_EndRequest(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的EndRequest"); }
} void context_BeginRequest(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的BeginRequest"); }
}
}
}
在web.config注册自定义的HttpModule
<?xml version="1.0" encoding="utf-8"?>
<!--
For more information on how to configure your ASP.NET application, please visit
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="MyHttpModule" type="MyHttpModule.MyHttpModule,MyHttpModule"/>
</modules>
</system.webServer>
</configuration>
浏览页面Default.aspx
那么在生命周期过程中的一系列的事件的执行顺序是怎样的呢?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace MyHttpModule
{
/// <summary>
/// 自定义HttpModule
/// </summary>
public class MyHttpModule : IHttpModule
{
public void Dispose()
{
throw new NotImplementedException();
} public void Init(HttpApplication context)
{
context.BeginRequest += context_BeginRequest;
context.EndRequest += context_EndRequest;
context.PostAcquireRequestState += context_PostAcquireRequestState;
context.PostAuthenticateRequest += context_PostAuthenticateRequest;
context.PostAuthorizeRequest += context_PostAuthorizeRequest;
context.PostLogRequest += context_PostLogRequest;
context.PostMapRequestHandler += context_PostMapRequestHandler;
context.PostRequestHandlerExecute += context_PostRequestHandlerExecute;
context.PostResolveRequestCache += context_PostResolveRequestCache;
context.PostUpdateRequestCache += context_PostUpdateRequestCache;
context.PreRequestHandlerExecute += context_PreRequestHandlerExecute;
context.PreSendRequestContent += context_PreSendRequestContent;
context.PreSendRequestHeaders += context_PreSendRequestHeaders;
context.RequestCompleted += context_RequestCompleted;
context.ResolveRequestCache += context_ResolveRequestCache;
context.UpdateRequestCache += context_UpdateRequestCache;
context.ReleaseRequestState += context_ReleaseRequestState;
} void context_UpdateRequestCache(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的UpdateRequestCache<br/>");
}
} void context_ResolveRequestCache(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的ResolveRequestCache<br/>");
}
} void context_RequestCompleted(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的RequestCompleted<br/>");
}
} void context_PreSendRequestHeaders(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的PreSendRequestHeaders<br/>");
}
} void context_PreSendRequestContent(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的PreSendRequestContent<br/>");
}
} void context_PreRequestHandlerExecute(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的PreRequestHandlerExecute<br/>");
}
} void context_PostUpdateRequestCache(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的PostUpdateRequestCache<br/>");
}
} void context_PostResolveRequestCache(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的PostResolveRequestCache<br/>");
}
} void context_PostRequestHandlerExecute(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的PostRequestHandlerExecut<br/>");
}
} void context_PostMapRequestHandler(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的PostMapRequestHandler<br/>");
}
} void context_PostLogRequest(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的PostLogRequest<br/>");
}
} void context_PostAuthorizeRequest(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的PostAuthorizeRequest<br/>");
}
} void context_PostAuthenticateRequest(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的PostAuthenticateRequest<br/>");
}
} void context_PostAcquireRequestState(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的PostAcquireRequestState<br/>");
}
} void context_ReleaseRequestState(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的ReleaseRequestState<br/>");
}
} void context_EndRequest(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的EndRequest<br/>");
}
} void context_BeginRequest(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app != null)
{
HttpContext context = app.Context;
HttpResponse response = app.Response;
response.Write("自定义HttpModule中的BeginRequest<br/>"); }
}
}
}
浏览结果

使用HttpModule终止此次Http请求
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
namespace MyHttpModule
{
public class EndModule : IHttpModule
{
public void Dispose()
{
throw new NotImplementedException();
} public void Init(HttpApplication context)
{
context.BeginRequest += context_BeginRequest;
} void context_BeginRequest(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender; application.CompleteRequest(); application.Context.Response.Write("请求被终止。"); }
}
}
结果
总结
这里介绍了在asp.net生命周期中一个最重要的接口IHttpModule,可以这样来形容该接口,事件接口,因为在实现类中的Init方法中,可以注册生命周期中的各种事件,并可以在事件中定义各种逻辑。
参考文章
一点一点学ASP.NET之基础概念——HttpModule 文野
IHttpModule的那些事的更多相关文章
- IHttpModule理解-知识补充
文章:IHttpModule的那些事 可以自定义类实现IHttpModule接口,然后实现接口方法Init,Init方法可以得到HttpApplication 的实例化对象. 然后给对象的事件的注册各 ...
- IHttpHandler的那些事
写在前面 从上家公司离职,在家休息,闲着无聊,觉得还是有必要将IHttpHanlder的内容,做一个总结.发现在写demo的过程中,总觉得有点生疏了,项目中很少使用自定义的类来实现该接口.当然,一般处 ...
- 准备.Net转前端开发-WPF界面框架那些事,搭建基础框架
题外话 最近都没怎么写博客,主要是最近在看WPF方面的书<wpf-4-unleashed.pdf>,挑了比较重要的几个章节学习了下WPF基础技术.另外,也把这本书推荐给目前正在从事WPF开 ...
- MVC4多语言IHttpModule实现
最近项目需要多语言环境了. 由于项目页面较多,逐个Action去读取资源文件不大现实.就想到了使用 IHttpModule配合MVC的路由规则来实现. 首先创建以个mvc4的应用程序,添加资源文件夹( ...
- IHttpModule与IHttpHandler的区别整理
IHttpModule与IHttpHandler的区别整理1.先后次序.先IHttpModule,后IHttpHandler. 注:Module要看你响应了哪个事件,一些事件是在Handler之前运行 ...
- HTTP请求处理流程、IHttphandler、IHttpModule
一.ASP.NET处理管道 Asp.net处理管道的第一步是创建HttpWorkerRequest对象,它包含于当前请求有关的所有信息. HttpWorkerRequest把请求传递给HttpRunt ...
- 【腾讯Bugly干货分享】H5 视频直播那些事
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57a42ee6503dfcb22007ede8 Dev Club 是一个交流移动 ...
- CSharpGL(31)[译]OpenGL渲染管道那些事
CSharpGL(31)[译]OpenGL渲染管道那些事 +BIT祝威+悄悄在此留下版了个权的信息说: 开始 自认为对OpenGL的掌握到了一个小瓶颈,现在回头细细地捋一遍OpenGL渲染管道应当是一 ...
- TODO:字节的那点事Go篇
TODO:字节的那点事Go篇 (本文go version go1.7.3 darwin/amd64) 在Golang中string底层是由byte数组组成的. fmt.Println(len(&quo ...
随机推荐
- 关于flume的filechannel的 full 问题
事务启动以后,批量向事务Transaction的一个putList的尾部写入,putlist是一个LinkedBlockingDeque . 事务提交的时候, 把putlist中的event批量移除, ...
- 使用Selenium慢慢向下滚动页面
我正试图从航班搜索页面抓取一些数据. 此页面以这种方式工作: 你填写一个表格,然后你点击按钮搜索 – 这没关系.当您单击该按钮时,您将被重定向到包含结果的页面,这就是问题所在.这个页面连续添加结果,例 ...
- 报错: WARN hdfs.DFSClient: Caught exception java.lang.InterruptedException
WARN hdfs.DFSClient: Caught exception java.lang.InterruptedException 而且日志中没有错误. 官网语句:$ bin/hdfs dfs ...
- 原生js三级联动
<!DOCTYPE html> <html lang="en"> <head> <title> 三级联动 </title> ...
- 20155316 实验一《Java开发环境的熟悉》实验报告
一.命令行下Java程序的开发 按照老师提供的步骤,运行程序如下: 二.IDEA下Java程序开发.调试 设置条件断点如下: 三.练习题 实现四则运算,并进行测试 实现效果:实现任意两个整数的加减乘除 ...
- 深入解析QML引擎, 第4部分: 自定义解析器
原文 QML Engine Internals, Part 4: Custom Parsers ——————————————————————————————————————————— 上一篇 绑定类型 ...
- C# List<string> 的Contains方法 是区分大小写的
List<string> 的Contains 是区分大小写的 代码: List<string> test = new List<string>(); test.A ...
- C#与mongoDB初始环境搭建
mongoDB官网https://www.mongodb.com/ mongoDB默认安装路径(Windows x64平台) C:\Program Files\MongoDB\Server\3.4\b ...
- Ubuntu用户设置文件说明
Ubuntu用户设置文件说明 Ubuntu作为Linux的一个发行版本,自然具有Linux系统的多用户特性.因为经常会使用和管理Ubuntu的用户,现将Ubuntu系统下的User的个性化配置整理如下 ...
- Matplotlib用法
一 环境安装 Make sure you have installed numpy. 先安装np pip install matplotlib (Python2.X) pip3 install mat ...