WapModule.cs:
public class WapModule:IHttpModule
{
   public void Init(HttpApplication context)
        {
            context.BeginRequest += new EventHandler(context_BeginRequest);
        }

// 处理BeginRequest 事件的实际代码
      void context_BeginRequest(object sender, EventArgs e)
        {
         ...............//todo:进入首页前的处理代码
     //eg:获得上下文
     //HttpApplication application = (HttpApplication)sender;
     //HttpContext context = application.Context;

}
   public void Dispose()
        {

}
}
Web.config:
<system.web>
<httpModules>
      <add name="MyModule" type="myWeb.WapModule"/>
</httpModules>   
</system.web>
这样假设将网站的首页设置为Default.aspx,访问Default.aspx页面时,在进入Default.aspx页面的代码之前会先进入WapModule.cs,然后根据WapModule.cs中的代码动态跳转到制定首页及记录一些访问者的机器信息等操作;

==============分割线======================

技术点:

(一)ASP.NET对请求处理的过程:

  当请求一个*.aspx文件的时候,这个请求会被inetinfo.exe进程截获,它判断文件的后缀(aspx)之后,将这个请求转交给ASPNET_ISAPI.dll,ASPNET_ISAPI.dll会通过http管道(Http PipeLine)将请求发送给ASPNET_WP.exe进程,在ASPNET_WP.exe进程中通过HttpRuntime来处理这个请求,处理完毕将结果返回客户端。

  inetinfo.exe进程:是www服务的进程,IIS服务和ASPNET_ISAPI.DLL都寄存在此进程中。

  ASPNET_ISAPI.DLL:是处理.aspx文件的win32组件。其实IIS服务器是只能识别.html文件的,当IIS服务器发现被请求的文件是.aspx文件时,IIS服务器将其交给aspnet_isapi.dll来处理。

  aspnet_wp.exe进程:ASP.NET框架进程,提供.net运行的托管环境,.net的CLR(公共语言运行时)就是寄存在此进程中。

  ASP.NET Framework处理一个Http Request的流程:

  
HttpRequest-->inetinfo.exe-->ASPNET_ISAPI.dll-->ASPNET_WP.exe-->HttpRuntime-->HttpApplication
Factory-->HttpApplication-->HttpModule-->HttpHandler
Factory-->HttpHandler-->HttpHandler.ProcessRequest()

  ASP.NET请求处理过程是基于管道模型的,这个管道模型是由多个HttpModule和HttpHandler组成,ASP.NET把
http请求依次传递给管道中各个HttpModule,最终被HttpHandler处理,处理完成后,再次经过管道中的HTTP模块,把结果返回给客
户端。我们可以在每个HttpModule中都可以干预请求的处理过程。

  注意:在http请求的处理过程中,只能调用一个HttpHandler,但可以调用多个HttpModule。

  

(二)HttpModule

  httpModules作用:

  当请求到达HttpModule的时候,系统还没有对这个请求真正处理,但是我
们可以在这个请求传递到处理中心(HttpHandler)之前附加一些其它信息,或者截获的这个请求并作一些额外的工作,也或者终止请求等。在
HttpHandler处理完请求之后,我们可以再在相应的HttpModule中把请求处理的结果进行再次加工返回客户端。

  HTTP模块是实现了System.Web.IhttpModule接口的类。

  IHttpModule接口的声明:

  public interface IHttpModule

  {

  void Init (HttpApplication context);

  void Dispose ();

  }

  Init 方法:系统初始化的时候自动调用,这个方法允许HTTP模块向HttpApplication 对象中的事件注册自己的事件处理程序。

  Dispose方法: 这个方法给予HTTP模块在对象被垃圾收集之前执行清理的机会。此方法一般无需编写代码。

  HTTP模块可以向System.Web.HttpApplication对象注册下面一系列事件:

  AcquireRequestState 当ASP.NET运行时准备好接收当前HTTP请求的对话状态的时候引发这个事件。

  AuthenticateRequest 当ASP.NET 运行时准备验证用户身份的时候引发这个事件。

  AuthorizeRequest 当ASP.NET运行时准备授权用户访问资源的时候引发这个事件。

  BeginRequest 当ASP.NET运行时接收到新的HTTP请求的时候引发这个事件。

  Disposed 当ASP.NET完成HTTP请求的处理过程时引发这个事件。

  EndRequest 把响应内容发送到客户端之前引发这个事件。

  Error 在处理HTTP请求的过程中出现未处理异常的时候引发这个事件。

  PostRequestHandlerExecute 在HTTP处理程序结束执行的时候引发这个事件。

  PreRequestHandlerExecute 在ASP.NET开始执行HTTP请求的处理程序之前引发这个事件。在这个事件之后,ASP.NET 把该请求转发给适当的HTTP处理程序。

  PreSendRequestContent 在ASP.NET把响应内容发送到客户端之前引发这个事件。这个事件允许我们在内容到达客户端之前改变响应内容。我们可以使用这个事件给页面输出添加用于所有页面的内容。例如通用菜单、头信息或脚信息。

  PreSendRequestHeaders 在ASP.NET把HTTP响应头信息发送给客户端之前引发这个事件。在头信息到达客户端之前,这个事件允许我们改变它的内容。我们可以使用这个事件在头信息中添加cookie和自定义数据。

  ReleaseRequestState 当ASP.NET结束所搜有的请求处理程序执行的时候引发这个事件。

  ResolveRequestCache 我们引发这个事件来决定是否可以使用从输出缓冲返回的内容来结束请求。这依赖于Web应用程序的输出缓冲时怎样设置的。

  UpdateRequestCache 当ASP.NET完成了当前的HTTP请求的处理,并且输出内容已经准备好添加给输出缓冲的时候,引发这个事件。这依赖于Web应用程序的输出缓冲是如何设置的。

  上面这么多的事件,我们看起来可能会有些眼晕,但没关系,下面一步一步地看。

  HttpModule生命周期示意图

  下面是事件的触发顺序:

  BeginRequest和PreRequestHandlerExecute之间的事件是在服务器执行HttpHandler处理之前触发。

  PostRequestHandlerExecute和PreSendRequestContent之间的事件是在服务器执行Handler处理之后触发。

(三)下面我们看一下如何使用HttpModule来实现我们日常的应用:

  HttpModule通过在某些事件中注册,把自己插入ASP.NET请求处理管道。当这些事件发生的时候,ASP.NET调用对相应的HTTP模块,这样该模块就能处理请求了。

  1、向每个页面动态添加一些备注或说明性的文字:

  有的网站每一个页面都会弹出一个广告或在每个页面都以注释形式(<!-- -->)加入网站的版权信息。如果在每个页面教编写这样的JS代码的话,对于大一点的网站,这种JS代码的编写与维护可是一个很繁琐枯燥的工作。

  有了HttpModule我们就可以很简单地解决这个问题了。HttpModule是客户端发出请求到客户端接收到服务器响应之间的一段必经之
路。我们完全可以在服务器处理完请求之后,并在向客户端发送响应文本之前这段时机,把这段注释文字添加到页面文本之后。这样,每一个页面请求都会被附加上
这段注释文字。

  这段代码究竟该在哪个事件里实现呢? PostRequestHandlerExecute和PreSendRequestContent之间的任何一个事件都可以,但我比较喜欢在EndRequest事件里编写代码。

  第一步:创建一个类库ClassLibrary831。

  第二步:编写一个类实现IHttpModule接口

  class TestModule:IHttpModule

  {

  public void Dispose()

  {

  }

  public void Init(HttpApplication context)

  {

  }

  }

  第三步:在Init事件中注册EndRequest事件,并实现事件处理方法

  class TestModule:IHttpModule

  {

  public void Dispose(){}

  public void Init(HttpApplication context)

  {

  context.EndRequest += new EventHandler(context_EndRequest);

  }

  void context_EndRequest(object sender, EventArgs e)

  {

  HttpApplication ha = (HttpApplication)sender;

  ha.Response.Write("<!--这是每个页面都会动态生成的文字。--grayworm-->");

  }

  }

  第四步:在Web.Conofig中注册一下这个HttpModule模块

  <httpModules>

  <add name="TestModule" type="ClassLibrary831.TestModule,ClassLibrary831"></add>

  </httpModules>

  name:模块名称,一般是类名

  type:有两部分组成,前半部分是命名空间和类名组成的全名,后半部分是程序集名称,如果类是直接放在App_Code文件夹中,那程序名称是App_Code。

  这样在Web站点是添加该类库的引用后,运行每个页面,会发现其源文件中都会加入“<!--这是每个页面都会动态生成的文字。--grayworm-->”这句话。同样的方法你也可以在其中加入JS代码。

  2、身份检查

  大家在作登录时,登录成功后,一般要把用户名放在Session中保存,在其它每一个页面的Page_Load事件中都检查Session中是否存在用户名,如果不存在就说明用户未登录,就不让其访问其中的内容。

  在比较大的程序中,这种做法实在是太笨拙,因为你几乎要在每一个页面中都加入检测Session的代码,导致难以开发和维护。下面我们看看如何使用HttpModule来减少我们的工作量

  由于在这里我们要用到Session中的内容,我们只能在AcquireRequestState和PreRequestHandlerExecute事件中编写代码,因为在HttpModule中只有这两事件中可以访问Session。这里我们选择PreRequestHandlerExecute事件编写代码。

  第一步:创建一个类库ClassLibrary831。

  第二步:编写一个类实现IHttpModule接口

  class TestModule:IHttpModule

  {

  public void Dispose()

  {

  }

  public void Init(HttpApplication context)

  {

  }

  }

  第三步:在Init事件中注册PreRequestHandlerExecute事件,并实现事件处理方法

class AuthenticModule:IHttpModule

  {

  public void Dispose(){}

  public void Init(HttpApplication context)

    {

      context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);

    }

  void context_PreRequestHandlerExecute(object sender, EventArgs e)

    {

      HttpApplication ha = (HttpApplication)sender;

      string path = ha.Context.Request.Url.ToString();

      int n = path.ToLower().IndexOf("Login.aspx");

  if (n == -1) //是否是登录页面,不是登录页面的话则进入{}

    {

      if (ha.Context.Session["user"] == null) //是否Session中有用户名,若是空的话,转向登录页。

    {

  ha.Context.Response.Redirect("Login.aspx?source=" + path);

    }

    }

  }

  }

第四步:在Login.aspx页面的“登录”按钮中加入下面代码

protected void Button1_Click(object sender, EventArgs e)

  {

    if(true) //判断用户名密码是否正确

   {

  if (Request.QueryString["source"] != null)

    {

      string s = Request.QueryString["source"].ToLower().ToString(); //取出从哪个页面转来的

      Session["user"] = txtUID.Text;

      Response.Redirect(s); //转到用户想去的页面

    }

  else

    {

      Response.Redirect("main.aspx"); //默认转向main.aspx

    }

   }

 }

第五步:在Web.Conofig中注册一下这个HttpModule模块

  <httpModules>

  <add name="TestModule" type="ClassLibrary831.TestModule,ClassLibrary831"></add>

  </httpModules>

  3、多模块的操作

  如果定义了多个HttpModule,在web.config文件中引入自定义HttpModule的顺序就决定了多个自定义HttpModule在处理一个HTTP请求的接管顺序。

httpModules与httpHandlers之httpModules(转载)的更多相关文章

  1. httpModules 与 httpHandlers

    ASP.NET对请求处理的过程:当请求一个*.aspx文件的时候,这个请求会被inetinfo.exe进程截获,它判断文件的后缀(aspx)之后,将这个请求转交给ASPNET_ISAPI.dll,AS ...

  2. ASP.NET中httpmodules与httphandlers全解析

    https://www.cnblogs.com/zpc870921/archive/2012/03/12/2391424.html https://www.cnblogs.com/PiaoMiaoGo ...

  3. .Net程序员必须要知道的东西之HttpModules与HttpHandlers介绍

    一.ASP.NET对请求处理的过程: 当客户端请求一个*.aspx文件的时候,这个请求会被inetinfo.exe进程截获,它判断文件的后缀(aspx)之后,将这个请求转交给ASPNET_ISAPI. ...

  4. (翻译)从底层了解ASP.NET体系结构 [转]

    转自:http://www.cnblogs.com/rijing2004/archive/2007/09/14/howaspnetwork.html 前言 关于ASP.NET的底层的工作机制,最近园子 ...

  5. 关于httpHandlers、handlers和httpModules、modules的那些配置中的各种问题

    在web.config中配置httpHandlers.handlers和httpModules.modules根据服务器环境不同设置各有不同 在IIS6及IIS7.0以上的经典模式中配置httpMod ...

  6. ASP.NET底层与各个组件的初步认识与理解 (转载)

    ASP.NET底层的初步认识与理解   最近在国外的网站乱走一通,发现一些比较好的文章,收集整理加于自己的理解,作为笔记形式记录下来,让以后自己有个回忆. ASP.NET是一个非常强大的构建Web应用 ...

  7. web.config详解(转载)

    该文为转载 原文地址:http://www.cnblogs.com/gaoweipeng/archive/2009/05/17/1458762.html 花了点时间整理了一下ASP.NET Web.c ...

  8. [转载]IIS7报500.23错误的解决方法

    原文出处: 原文作者:pizibaidu 原文链接:http://pizibaidu.blog.51cto.com/1361909/1794446 背景:今天公司终端上有一个功能打开异常,报500错误 ...

  9. WebConfig配置文件详解(转载自逆心的博客)

    <?xml version="1.0"?> <!--注意: 除了手动编辑此文件以外,您还可以使用 Web 管理工具来配置应用程序的设置.可以使用 Visual S ...

随机推荐

  1. [CareerCup] 5.1 Insert Bits 插入位

    5.1 You are given two 32-bit numbers, N and M, and two bit positions, land j. Write a method to inse ...

  2. Linux 基础入门

    实验一(Linux 系统简介): 了解了一些有关Linux的重要人物,以及 实验二(基本概念及操作): Linux终端 1.Terminal(终端):当你切换到其中一个终端后想要切换回图形界面,你可以 ...

  3. 如何抛出未认证(Unauthorized=401)异常代码

    throw new System.ServiceModel.Web.WebFaultException<string>("\"mes\":\"认证信 ...

  4. dom4j 使用总结

    dom4j是一个Java的XML API,类似于jdom,用来读写XML文件 dom4j的使用方法简单总结来说如下: ①可以创建一个新的xml文件 ②利用SAXReader和File对象创建一个已存在 ...

  5. 备忘:SSRS技巧三则

    前言 最近在弄SSRS,发现了三个小技巧.在此记录一下.免得以后忘了. 技巧 1. SSRS输出成EXCEL时,让两个dataset各占一个sheet, 这个简单,在其中一个table的属性加上pag ...

  6. groovyConsole — the Groovy Swing console

    1. Groovy : Groovy Console The Groovy Swing Console allows a user to enter and run Groovy scripts. T ...

  7. 每天一个linux命令(38):vmstat命令

    vmstat 是Virtual Meomory Statistics(虚拟内存统计)的缩写,可对操作系统的虚拟内存.进程.CPU活动进行监控.他是对系统的整体 情况进行统计,不足之处是无法对某个进程进 ...

  8. js回掉页面后台代码-简单demo

    后台代码: public partial class WebForm1 : System.Web.UI.Page, ICallbackEventHandler { protected void Pag ...

  9. “耐撕”团队 2016.03.30 站立会议

    1. 时间: 16:45--17:05  总计:20分钟 2. 成员: Z 郑蕊 * 组长 (博客:http://www.cnblogs.com/zhengrui0452/), P 濮成林(博客:ht ...

  10. Ibatis学习总结7--SqlMapClient 执行 SQL 语句

    SqlMapCient 类提供了执行所有 mapped statement 的 API.这些方法如下: public int insert(String statementName, Object p ...