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. EntityFramework中几种更改数据的方式

    首先声明个实体类,该实体类是EntityFrameWork自动生成的,对应数据表Test结构如下 public partial class Test { public int Id{ get; set ...

  2. GUID全局唯一标识符

         全局唯一标识符(GUID,Globally Unique Identifier)是一种由算法生成的二进制长度为128位的数字标识符.GUID主要用于在拥有多个节点.多台计算机的网络或系统中. ...

  3. oracle分组查询实例ORA-00979和ORA-00937错误分析

    select J.ZWJGH,J.CZZXBH,J.JZZT,J.CWNY,J.JZPZH sum(J.FSE)<!-- 聚合函数字段没在分组条件中--> from JZPZXX J &l ...

  4. MYSQL 练习

    导出现有数据库数据: mysqldump -u用户名 -p密码 数据库名称 >导出文件路径           # 结构+数据 mysqldump -u用户名 -p密码 -d 数据库名称 > ...

  5. CentOS安装zip unzip命令

    yum install zip unzip

  6. maven 跳过测试 打包 及上传命令

    [main] ERROR org.apache.maven.cli.MavenCli - Failed to execute goal org.apache.maven.plugins:maven-s ...

  7. Atitit.excel导出 功能解决方案 php java C#.net版总集合.doc

    Atitit.excel导出 功能解决方案 php java C#.net版总集合.docx 1.1. Excel的保存格式office2003 office2007/2010格式1 1.2. 类库选 ...

  8. ADO.NET(数据访问技术)

    简单的说,C#已经内置了一些类,我们可以利用这些类来访问数据库.在这里,我们假设读者已经熟悉SqlServer数据库或者其它数据库(我以后也会补上相关内容).我们如何来实现这项技术呢?大致可以分为三个 ...

  9. 03Mybatis_mybatis框架原理——执行流程

    mybatis的框架的原理(执行流程).

  10. css知多少(10)——display

    1. 引言 网页的所有元素,除了“块”就是“流”,而且“流”都是包含在“块”里面的(最外层的body就是一个“块”).在本系列一开始讲<浏览器默认样式>的时候,大家也都看到了浏览器默认样式 ...