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 安装Redis程序
一.系统环境 1.硬件系统:Windows7 64位 2.软件环境: Redis 64位 3.2.100.Redis Desktop Manager. 二.Redis安装 下载地址:https://g ...
- mysql secure_file_priv 文件读写问题
secure_file_priv特性 使用 show global variables like '%secure%'; 查询显示 secure_file_priv的值为null,那么secure_f ...
- scala (1) for 循环
scala if else 判断 (1)在scala中末尾不需要添加 分号 作为语句的终结符. val name = "Leo" (2) 在 scala 中 if else ...
- Hadoop命令大全
Hadoop命令大全 分类: 云计算2011-03-01 15:04 6852人阅读 评论(0) 收藏 举报 hadoop作业任务集群class脚本 1.列出所有Hadoop Shell支持的命令 ...
- 20155319 《Java程序设计》实验一(Java开发环境的熟悉)实验报告
20155319 <Java程序设计>实验一(Java开发环境的熟悉)实验报告 一.实验内容及步骤 (一)使用JDK编译.运行简单的java程序 命令行下的程序开发 步骤一:打开mac下的 ...
- # 第二周c实践所遇见的问题
第二周c实践所遇见的问题 地址符 在编程练习中时常忘记写入地址符,造成过运行错误,运行结果错误的惨痛教训,一个小小的错误耗费了很长的时间来寻找错误之处,养成写代码的一些好习惯势在必行.牢记scanf( ...
- SSM框架及例子(转)
SSM 手把手教你整合最优雅SSM框架:SpringMVC + Spring + MyBatis 博客地址:http://blog.csdn.net/qq598535550/article/detai ...
- BZOJ054_移动玩具_KEY
题目传送门 这道题我写IDA*写挂了,TLE+WA,只AC了两个点. 这道题标算BFS+状态压缩. code: /******************************************* ...
- 【LG5022】[NOIP2018]旅行
[LG5022][NOIP2018]旅行 题面 洛谷 题解 首先考虑一棵树的部分分怎么打 直接从根节点开始\(dfs\),依次选择编号最小的儿子即可 而此题是一个基环树 怎么办呢? 可以断掉环上的一条 ...
- JS的发布订阅模式
JS的发布订阅模式 这里要说明一下什么是发布-订阅模式 发布-订阅模式里面包含了三个模块,发布者,订阅者和处理中心.这里处理中心相当于报刊办事大厅.发布者相当与某个杂志负责人,他来中心这注册一个的杂志 ...