写在前面

关于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的那些事的更多相关文章

  1. IHttpModule理解-知识补充

    文章:IHttpModule的那些事 可以自定义类实现IHttpModule接口,然后实现接口方法Init,Init方法可以得到HttpApplication 的实例化对象. 然后给对象的事件的注册各 ...

  2. IHttpHandler的那些事

    写在前面 从上家公司离职,在家休息,闲着无聊,觉得还是有必要将IHttpHanlder的内容,做一个总结.发现在写demo的过程中,总觉得有点生疏了,项目中很少使用自定义的类来实现该接口.当然,一般处 ...

  3. 准备.Net转前端开发-WPF界面框架那些事,搭建基础框架

    题外话 最近都没怎么写博客,主要是最近在看WPF方面的书<wpf-4-unleashed.pdf>,挑了比较重要的几个章节学习了下WPF基础技术.另外,也把这本书推荐给目前正在从事WPF开 ...

  4. MVC4多语言IHttpModule实现

    最近项目需要多语言环境了. 由于项目页面较多,逐个Action去读取资源文件不大现实.就想到了使用 IHttpModule配合MVC的路由规则来实现. 首先创建以个mvc4的应用程序,添加资源文件夹( ...

  5. IHttpModule与IHttpHandler的区别整理

    IHttpModule与IHttpHandler的区别整理1.先后次序.先IHttpModule,后IHttpHandler. 注:Module要看你响应了哪个事件,一些事件是在Handler之前运行 ...

  6. HTTP请求处理流程、IHttphandler、IHttpModule

    一.ASP.NET处理管道 Asp.net处理管道的第一步是创建HttpWorkerRequest对象,它包含于当前请求有关的所有信息. HttpWorkerRequest把请求传递给HttpRunt ...

  7. 【腾讯Bugly干货分享】H5 视频直播那些事

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57a42ee6503dfcb22007ede8 Dev Club 是一个交流移动 ...

  8. CSharpGL(31)[译]OpenGL渲染管道那些事

    CSharpGL(31)[译]OpenGL渲染管道那些事 +BIT祝威+悄悄在此留下版了个权的信息说: 开始 自认为对OpenGL的掌握到了一个小瓶颈,现在回头细细地捋一遍OpenGL渲染管道应当是一 ...

  9. TODO:字节的那点事Go篇

    TODO:字节的那点事Go篇 (本文go version go1.7.3 darwin/amd64) 在Golang中string底层是由byte数组组成的. fmt.Println(len(&quo ...

随机推荐

  1. golang学习总结

    目录 1. 初识go语言 1.1 Hello World 1.2 go 数据类型 布尔: 整型: 浮点型: 字符类型 字符串型: 复数类型: 1.3 变量常量 局部变量: 全局变量 常量 1.5 字符 ...

  2. PHP程序员的技术成长规划 第二阶段:提高阶段

    第二阶段:提高阶段 (中级PHP程序员) 重点:提高针对LNMP的技能,能够更全面的对LNMP有熟练的应用.目标:能够随时随地搭建好LNMP环境,快速完成常规配置:能够追查解决大部分遇到的开发和线上环 ...

  3. 在AI人工智能中如何巧妙学习大数据编程,成为五十万年薪的佼佼者

    编辑 ai狗年 大数据和人工智能的关系,首先要说什么是大数据.这些年来,大数据先是被神化,继而又被妖魔化,到了今天,其实谁也不知道别人所谓的大数据指的是什么.我大数据从业者,建了一个大数据资源共享群1 ...

  4. BurpSuite—-Scanner模块(漏洞扫描)

    一.简介 Burp Scanner 是一个进行自动发现 web 应用程序的安全漏洞的工具.它是为渗透测试人员设计的,并且它和你现有的手动执行进行的 web 应用程序半自动渗透测试的技术方法很相似. 使 ...

  5. PMP十五至尊图(第六版)

    PMP(Project Management Professinoal)项目经理专业资格认证,由美国项目管理学会PMI(Project Management Institute)发起并组织的一种资格认 ...

  6. FLEX拖动时复制图片

    <?xml version="1.0" encoding="utf-8"?><mx:Application xmlns:mx="ht ...

  7. 20155230 实验四《android程序设计》实验报告

    20155230 实验四<Android程序设计>实验报告 一.安装Android Stuidio 二.从一个活动启动另一个活动 在启动活动的活动里添加如下语句即可 Intent inte ...

  8. 「PKUWC2018」Minimax

    题面 题解 强势安利一波巨佬的$blog$ 线段树合并吼题啊 合并的时候要记一下$A$点权值小于$l$的概率和$A$点权值大于$r$的概率,对$B$点同样做 时空复杂度$\text O(nlogw)$ ...

  9. vue 3.0使用 BUG解决

    最近在做vue的项目,吊进了很多坑,这些坑很浅,但一旦掉进去了,不花点功夫还爬不出来.所以总结下,当做下笔记,持续更新 1.<router-link> 里加的事件没反应 错误代码: < ...

  10. QML和JS引擎的关系以及调用c++函数的原理

    首先推荐几篇博客 1.深入解析QML引擎, 第1部分:QML文件加载 https://www.cnblogs.com/wzxNote/p/10569535.html 2.深入解析QML引擎, 第2部分 ...