HttpModule是如何工作的

当一个HTTP请求到达HttpModule时,整个ASP.NET Framework系统还并没有对这个HTTP请求做任何处理,也就是说此时对于HTTP请求来讲,HttpModule是一个HTTP请求的“必经之路”,所以可以在这个HTTP请求传递到真正的请求处理中心(HttpHandler)之前附加一些需要的信息在这个HTTP请求信息之上,或者针对截获的这个HTTP请求信息作一些额外的工作,或者在某些情况下干脆终止满足一些条件的HTTP请求,从而可以起到一个Filter过滤器的作用。

示例1:

using System;

using System.Collections.Generic;

using System.Text;

using System.Web;

namespace MyHttpModule

{

/// <summary>

/// 说明:用来实现自己的HttpModule类。

/// 作者:文野

/// 联系:stwyhm@cnblogs.com

/// </summary>

public class MyFirstHttpModule : IHttpModule

{

private void Application_BeginRequest(object sender, EventArgs e)

{

HttpApplication application = (HttpApplication)sender;

HttpContext context = application.Context;

HttpRequest request = application.Request;

HttpResponse response = application.Response;

response.Write("我来自自定义HttpModule中的BeginRequest<br />");

}

private void Application_EndRequest(object sender, EventArgs e)

{

HttpApplication application = (HttpApplication)sender;

HttpContext context = application.Context;

HttpRequest request = application.Request;

HttpResponse response = application.Response;

response.Write("我来自自定义HttpModule中的EndRequest<br />");

}

#region IHttpModule 成员

public void Dispose()

{}

public void Init(HttpApplication application)

{

application.BeginRequest += new EventHandler(Application_BeginRequest);

application.EndRequest += new EventHandler(Application_EndRequest);

}

#endregion

}

}

在Web.config进行如下配置

<add name="MyFirstHttpModule" type="MyHttpModule.MyFirstHttpModule,MyHttpModule"/>

深入了解HttpModule

一个HTTP请求在HttpModule容器的传递过程中,会在某一时刻(ResolveRequestCache事件)将这个HTTP请求传递给HttpHandler容器。在这个事件之后,HttpModule容器会建立一个HttpHandler的入口实例,但是此时并没有将HTTP请求控制权交出,而是继续触发AcquireRequestState事件以及PreRequestHandlerExcute事件。在PreRequestHandlerExcute事件之后,HttpModule窗口就会将控制权暂时交给HttpHandler容器,以便进行真正的HTTP请求处理工作。

而在HttpHandler容器内部会执行ProcessRequest方法来处理HTTP请求。在容器HttpHandler处理完毕整个HTTP请求之后,会将控制权交还给HttpModule,HttpModule则会继续对处理完毕的HTTP请求信息流进行层层的转交动作,直到返回到客户端为止。

图1:HttpModule生命周期示意图

示例2:验证HttpModule生命周期

using System;

using System.Collections.Generic;

using System.Text;

using System.Web;

namespace MyHttpModule

{

public class ValidaterHttpModule : IHttpModule

{

#region IHttpModule 成员

public void Dispose()

{}

public void Init(HttpApplication application)

{

application.BeginRequest += new EventHandler(application_BeginRequest);

application.EndRequest += new EventHandler(application_EndRequest);

application.PreRequestHandlerExecute += new EventHandler(application_PreRequestHandlerExecute);

application.PostRequestHandlerExecute += new EventHandler(application_PostRequestHandlerExecute);

application.ReleaseRequestState += new EventHandler(application_ReleaseRequestState);

application.AcquireRequestState += new EventHandler(application_AcquireRequestState);

application.AuthenticateRequest += new EventHandler(application_AuthenticateRequest);

application.AuthorizeRequest += new EventHandler(application_AuthorizeRequest);

application.ResolveRequestCache += new EventHandler(application_ResolveRequestCache);

application.PreSendRequestHeaders += new EventHandler(application_PreSendRequestHeaders);

application.PreSendRequestContent += new EventHandler(application_PreSendRequestContent);

}

void application_PreSendRequestContent(object sender, EventArgs e)

{

HttpApplication application = (HttpApplication)sender;

application.Context.Response.Write("application_PreSendRequestContent<br/>");

}

void application_PreSendRequestHeaders(object sender, EventArgs e)

{

HttpApplication application = (HttpApplication)sender;

application.Context.Response.Write("application_PreSendRequestHeaders<br/>");

}

void application_ResolveRequestCache(object sender, EventArgs e)

{

HttpApplication application = (HttpApplication)sender;

application.Context.Response.Write("application_ResolveRequestCache<br/>");

}

void application_AuthorizeRequest(object sender, EventArgs e)

{

HttpApplication application = (HttpApplication)sender;

application.Context.Response.Write("application_AuthorizeRequest<br/>");

}

void application_AuthenticateRequest(object sender, EventArgs e)

{

HttpApplication application = (HttpApplication)sender;

application.Context.Response.Write("application_AuthenticateRequest<br/>");

}

void application_AcquireRequestState(object sender, EventArgs e)

{

HttpApplication application = (HttpApplication)sender;

application.Context.Response.Write("application_AcquireRequestState<br/>");

}

void application_ReleaseRequestState(object sender, EventArgs e)

{

HttpApplication application = (HttpApplication)sender;

application.Context.Response.Write("application_ReleaseRequestState<br/>");

}

void application_PostRequestHandlerExecute(object sender, EventArgs e)

{

HttpApplication application = (HttpApplication)sender;

application.Context.Response.Write("application_PostRequestHandlerExecute<br/>");

}

void application_PreRequestHandlerExecute(object sender, EventArgs e)

{

HttpApplication application = (HttpApplication)sender;

application.Context.Response.Write("application_PreRequestHandlerExecute<br/>");

}

void application_EndRequest(object sender, EventArgs e)

{

HttpApplication application = (HttpApplication)sender;

application.Context.Response.Write("application_EndRequest<br/>");

}

void application_BeginRequest(object sender, EventArgs e)

{

HttpApplication application = (HttpApplication)sender;

application.Context.Response.Write("application_BeginRequest<br/>");

}

#endregion

}

}

多个自定义的Http Module的运作

从运行结果可以看到,在web.config文件中引入自定义HttpModule的顺序就决定了多个自定义HttpModule在处理一个HTTP请求的接管顺序。注:系统默认那几个HttpModule是最先衩ASP.NET Framework所加载上去的。

示例3:(代码类同示例2)

在HttpModule中终止此次的HTTP请求

可以利用HttpModule通过调用HttpApplication.CompleteRequest()方法实现当满足某一个条件时终止此次的HTTP请求。

需要注意的是,即使调用了HttpApplication.CompleteRequest()方法终止了一个HTTP请求,ASP.NET Framework仍然会触发HttpApplication后面的这3个事件:EndRequest事件、PreSendRequestHeaders事件、PreSendRequestContent事件。

如果存在多个自定义的HttpModule的话,当Module1终止了一个HTTP请求,这个HTTP请求将不会再触发Module2中相应的事件了,但Module2的最后三个事件仍会被触发。

示例4:

using System;

using System.Collections.Generic;

using System.Text;

using System.Web;

namespace MyHttpModule

{

public class CompleteRequestHttpModule : IHttpModule

{

#region IHttpModule 成员

public void Dispose()

{}

public void Init(HttpApplication application)

{

application.BeginRequest += new EventHandler(Application_BeginRequest);

}

void Application_BeginRequest(object sender, EventArgs e)

{

HttpApplication application = (HttpApplication)sender;

application.CompleteRequest();

application.Context.Response.Write("请求被终止。");

}

#endregion

}

}

HttpModule的更多相关文章

  1. ASP.NET使用HttpModule压缩并删除空白Html请求

    当我们压缩我的Response后再传到Client端时,可以明显节省宽带. 提升Site的性能. 现在的浏览器大部分都支持Gzip,Deflate压缩. 同时我们还可以删除一些空白段,空行,注释等以使 ...

  2. [转]HttpModule的认识

    HttpModule是向实现类提供模块初始化和处置事件.当一个HTTP请求到达HttpModule时,整个ASP.NET Framework系统还并没有对这个HTTP请求做任何处理,也就是说此时对于H ...

  3. [转]ASP.NET应用程序生命周期趣谈(三) HttpModule

    在之前的文章中,我们提到过P_Module(HttpModule)这个能干的程序员哥们儿,它通过在项目经理HttpApplication那里得到的授权,插手整个应用程序级别的事件处理.所有的HttpM ...

  4. 基于HttpModule的简单.NET网站授权方案

    摘要 本文介绍一种入门级的网站授权(注:这里所指的授权指的是注册码效果,而不是网站登陆时的身份授权)方案,仅供学习交流及对付小白客户使用.复杂的网站授权涉及网站加密等一系列复杂的技术,不做本文介绍内容 ...

  5. httphandler和httpmodule的区别

    ASP.Net处理Http Request时,使用Pipeline(管道)方式,由各个HttpModule对请求进行处理,然后到达 HttpHandler,HttpHandler处理完之后,仍经过Pi ...

  6. 你必须知道ASP.NET知识------关于动态注册httpmodule(对不起汤姆大叔)

    一.关于动态注册的问题 很多人看过汤姆大叔的MVC之前的那点事儿系列(6):动态注册HttpModule ,其实汤姆大叔没有发现httpmodule动态注册的根本机制在哪里. 亦即:怎么动态注册?为什 ...

  7. Asp.Net通过HttpModule实现URL重写

    首先总结一下为什么要对URL进行Rewrite,比如我可以把/Default.aspx?param=3替换成/Home/Default/3(类似mvc). 一.缩短url,隐藏实际路径提高安全性; 二 ...

  8. Could not load type 'System.ServiceModel.Activation.HttpModule' from assembly 'System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'

    Could not load type 'System.ServiceModel.Activation.HttpModule' from assembly 'System.ServiceModel, ...

  9. 部署网站出现System.ServiceModel.Activation.HttpModule错误

    1. 部署网站到IIS7.5,Window 2008的时候出现这个错误 2. 错误信息 Server Error in '/' Application. Could not load type 'Sy ...

  10. HttpModule的认识

    1.asp.net的HTTP请求处理过程 说明: (1).客户端浏览器向服务器发出一个http请求,此请求会被inetinfo.exe进程截获,然后转交给aspnet_isapi.dll进程,接着它又 ...

随机推荐

  1. 富客户端 wpf, Winform 多线程更新UI控件

    前言 在富客户端的app中,如果在主线程中运行一些长时间的任务,那么应用程序的UI就不能正常相应.因为主线程要负责消息循环,相应鼠标等事件还有展现UI. 因此我们可以开启一个线程来格外处理需要长时间的 ...

  2. sql 指定值排序

    --SELECT [ButtonName] as text,[FunctionName] as handler,[iconCls] --FROM [ButtonTable] where PKID in ...

  3. 泛函编程(36)-泛函Stream IO:IO数据源-IO Source & Sink

    上期我们讨论了IO处理过程:Process[I,O].我们说Process就像电视信号盒子一样有输入端和输出端两头.Process之间可以用一个Process的输出端与另一个Process的输入端连接 ...

  4. java 小程序-- 汉诺塔

    1.code public static void main(String[] args) { ; moveDish(, 'A', 'B', 'C'); } public static void mo ...

  5. Genymotion无法下载OVA文件

    百度 下载Genymotion离线OVA文件(http://pan.baidu.com/s/1jIe5pjC ) 将OVA离线文件放到这个目录下:C:\Users\Administrator\AppD ...

  6. Linux下如何查看哪个进程占用内存多?

    1.top top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器 可以直接使用top命令后,查看%MEM的内容.可以选择按进程查看或者 ...

  7. Java新集合示意图

    Java的新集合实际上只有3个集合组件:①Map ②List ③Set 在Java 1.2后应该尽量避免使用Hashtable,Vector 和Stack: 假如在一个列表中部进行大量的插入和删除操作 ...

  8. javascript模板库jsrender加载并缓存外部模板文件

    前一篇说了jsrender嵌套循环的使用,在SPA的应用中,广泛使用的一个点就是view模板,使用了SPA之后,每个业务页面不再是独立的html,仅仅是一个segment,所以通常这些segment会 ...

  9. Ionic 今天发布了Windows 桌面版的IDE Ionic Lab

    Ionic简介: Ionic 是一个强大的 HTML5 应用程序开发框架,号称 Advanced HTML5 Hybrid Mobile AppFramework 是 AngularJS 移动端解决方 ...

  10. 对jQuery选择器的总结

    jQuery基础选择器 $("div*")获取div下面的所有元素 $(".red,.green").html("怎么") // 需要注意的 ...