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 ...
随机推荐
- Windows Oracle连接ORA-12541:TNS:无监听程序
上面两篇是安装和连接,这里写一下碰到的问题,安装后使用SQL Developer连接出现ORA-12541:TNS:无监听程序.网上搜了一下是安装的Oracle中自带的JDK是32位,而程序中使用的S ...
- spark RDD官网RDD编程指南
http://spark.apache.org/docs/latest/rdd-programming-guide.html#using-the-shell Overview(概述) 在较高的层次上, ...
- 大数据IDEA调试flink程序
Flink在IDEA中开发是一件比较困难的事情,网上没有参考资料,就算就业说的太过笼统,不知道是会了不说还是不会瞎说,为了解决flink这个问题,本人特别做了一遍开发的简单说明.主要考虑两个问题,1. ...
- 为树莓派添加一个强实时性前端[原创cnblogs.com/helesheng]
树莓派是最近流行嵌入式平台,其自由的开源特性以及低廉的价格,吸引了来 自全球的大量极客和计算机大咖的关注.来自各大树莓派社区的幕后英雄,无私地在这个开源硬件平台上做了大量的工作,将其打造成了世界上通用 ...
- SDR软件无线电知识要点(一)噪声系数与噪声因子
SDR软件无线电知识要点(一)噪声系数与噪声因子 信号质量如何评估 Noise Figure (NF) or sensitivity and Error Vector Magnitude (EVM) ...
- verilog中初值定义
在利用verilog进行开发时,往往需要对某些寄存器进行赋初值,下面根据笔者在设计中遇到的情况进行分析. 例如下面是实现流水灯(4个led),代码如下: module ledrun ( input ...
- Java - JavaMail - 利用 JavaMail 发邮件的 小demo
1. 概述 面试的时候, 被问到一些乱七八糟的运维知识 虽然我不是干运维的, 但是最后却告诉我专业知识深度不够, 感觉很难受 又回到了一个烦人的问题 工作没有深度的情况下, 你该如何的提升自己, 并且 ...
- 20155236 《Java程序设计》实验二实验报告
20155236 <Java程序设计>实验一(Java开发环境的熟悉)实验报告 一.实验内容及步骤 实验内容 1.初步掌握单元测试和TDD 2.理解并掌握面向对象三要素:封装.继承.多态 ...
- 20155301 《Java程序设计》实验五网络编程与安全
20155301 <Java程序设计>实验五网络编程与安全 实验内容 实验1: 两人一组结对编程:参考http://www.cnblogs.com/rocedu/p/6766748.htm ...
- XDS100V3连接Pandaboard ES OMAP4460开发板
1. 硬件连接如下 2. 使用CCS创建工程,不过好像没有ARM9的内核吧?为啥会出现? 3. 创建目标配置文件 4. 不过确实有ARM9的内核,两个A9内核,一个DSP C64X内核,两个M3的内核 ...