ASP.NET 处理请求的过程

  • inetinfo.exe:www 服务进程,IIS 服务 和 ASPNET_ISAPI.dll 都寄存在此进程中。
  • ASPNET_ISAPI.dll:处理 .aspx 文件的 win32 组件。其实,IIS 服务器只能识别 .html 文件的,当发现被请求的文件是 .aspx 文件时,IIS 服务器将其交给 aspnet_isapi.dll 来处理。
  • aspnet_wp.exe 进程:ASP.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 请求处理过程是基于管道模型的,ASP.NET 把 http 请求依次传递给管道中各个 HttpModule,最终被 HttpHandler 处理,处理完成后,再次经过管道中的 HttpModule,把结果返回给客户端。注意:在 http 请求的处理过程中,只能调用一个 HttpHandler,但可以调用多个 HttpModule。

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

HttpModule

HttpModule 是实现了 System.Web.IhttpModule 接口的类。IHttpModule 接口的声明:

public interface IHttpModule

{

    // 给予 HTTP 模块在对象被垃圾收集之前执行清理的机会,一般无需编写代码。

    void Dispose();

 

    // 初始化时自动调用,可在这里向 HttpApplication 对象中的事件注册自己的事件处理程序

    void Init(HttpApplication context);

}

HttpModule 可以向 System.Web.HttpApplication 对象注册下面一系列事件(事件触发顺序已排序):

  1. application_BeginRequest:当 ASP.NET 运行时接收到新的 HTTP 请求时触发。
  2. application_AuthenticateRequest:当 ASP.NET 运行时准备验证用户身份时触发。
  3. application_AuthorizeRequest:当 ASP.NET 运行时准备授权用户访问资源的时候触发。
  4. application_ResolveRequestCache:我们引发这个事件来决定是否可以使用从输出缓存返回的内容来结束请求。但这依赖于 Web 应用程序的输出缓存是怎样设置的。
  5. application_AcquireRequestState:当 ASP.NET 运行时准备好接收当前 HTTP 请求的会话状态的时候引发这个事件。
  6. application_PreRequestHandlerExecute:在 ASP.NET 开始执行 HTTP 请求的处理程序之前引发这个事件。在这个事件之后,ASP.NET 把该请求转发给适当的HTTP处理程序。
  7. application_PostRequestHandlerExecute:在 HTTP 处理程序结束执行的时候引发这个事件。
  8. application_ReleaseRequestState:当 ASP.NET 结束所有的请求处理程序执行的时候引发这个事件。
  9. application_EndRequest:把响应内容发送到客户端之前引发这个事件。
  10. application_PreSendRequestHeaders:在 ASP.NET 把 HTTP 响应头信息发送给客户端之前引发这个事件。在头信息到达客户端之前,这个事件允许我们改变它的内容。我们可以使用这个事件在头信息中添加cookie 和自定义数据。
  11. application_PreSendRequestContent:在 ASP.NET 把响应内容发送到客户端之前引发这个事件。这个事件允许我们在内容到达客户端之前改变响应内容。我们可以使用这个事件给页面输出添加用于所有页面的内容。例如通用菜单、头信息、脚信息或某些注释与标记。

其余,还有 Error 事件(在处理 HTTP 请求的过程中出现未处理的异常时触发),Deposed 事件(当 ASP.NET 完成 HTTP 请求的处理过程时触发),UpdateRequestCache 事件(当 ASP.NET 完成了当前的 HTTP 请求的处理,并且输出内容已经准备好添加给输出缓存时触发。这依赖于 Web 应用程序的输出缓存是如何设置的)。

HttpModule & HttpHandler 的生命周期图:

HttpModule 使用示例1

有的网站每一个页面都会弹出一个广告或在每个页面都以注释形式(<!-- -->)加入网站的版权信息。如果在每个页面教编写这样的 JS 代码,编写会很繁琐,更改和维护将非常困难。
       HttpModule 是客户端发出请求到客户端接收到服务器响应之间的一段必经之路。我们完全可以在服务器处理完请求之后,并在向客户端发送响应文本之前这段时机,把这段注释文字添加到页面文本之后。这样,每一个页面请求都会被附加上这段注释文字。那么,这段代码究竟该在哪个事件里实现呢? PostRequestHandlerExecute 和 PreSendRequestContent 之间的任何一个事件都可以,但一般会在 EndRequest 事件里编写代码,具体实现步骤如下:

  1. 添加自定义的管道类,并实现 IHttpModule 接口
  2. 在 Init 事件中注册 EndRequest 事件,实现事件处理方法
  3. 在 Web.Conofig 中注册自定义 HttpModule
public class TestModule : IHttpModule

{

    public void Dispose()

    {

       

    }

 

    public void Init(HttpApplication context)

    {

        context.EndRequest +=  context_EndRequest;

    }

 

    void context_EndRequest(object sender, EventArgs e)

    {

        ((HttpApplication)sender).Response.Write("<!-- 公司版权 -->");

    }

}

<httpModules>

  <add name="TestModule" type="ASP.NET_Web_Form.Util.TestModule,ASP.NET_Web_Form.Util"/>

</httpModules>

HttpModule 使用示例2

在作登录时,登录成功后,一般要把用户名放在 Session 中保存,在其它每一个页面的 Page_Load 事件中都检查 Session 中是否存在用户名,如果不存在就说明用户未登录,就不让其访问其中的内容。但这种做法实在是太笨拙,几乎要在每一个页面中都加入检测 Session 的代码,导致难以开发和维护。下面我们看看如何使用 HttpModule 来减少我们的工作量。(如果每个页面都有共同的父类,例如 BasePage,那么在父类的 Load 事件中检测也是一样的只需写一次检测代码)
       由于这里要用到 Session 中的内容,我们只能在 AcquireRequestState 和 PreRequestHandlerExecute 事件中编写代码,因为在 HttpModule 中只有这两事件中可以访问 Session。这里可以选择PreRequestHandlerExecute 事件编写代码,具体实现比较简单,就不贴代码了。

HttpHandler

HttpHandler 是 HTTP 请求的处理中心,真正地对客户端请求的服务器页面做出编译和执行,并将处理过后的信息附加在 HTTP 请求信息流中再次返回到 HttpModule 中。与 HttpModule 不同,一旦定义了自己的HttpHandler 类,那么它对系统的 HttpHandler 的关系将是“覆盖”。

在 web.config 中配置 HttpHandler 节时,你可以指定 HTTP 的动词(GET,POST),指定要处理的资源是什么,以及用什么 HttpHandler 来进行。

另外,如果要在 HttpHandler 中使用 Session,那必须把该 HttpHandler 实现 IRequiresSessionState 接口,IRequiresSessionState 接口是个空接口,它没有抽象方法,只是一个标记接口。

本文参考文献:http://www.cnblogs.com/yuanyuan/archive/2010/11/15/1877709.html

HttpModule & HttpHandler的更多相关文章

  1. ASP.NET 管道事件与HttpModule, HttpHandler简单理解 -摘自网络

    第一部分:转载自Artech  IIS与ASP.NET管道 ASP.NET管道 以IIS 6.0为例,在工作进程w3wp.exe中,利用Aspnet_ispai.dll加载.NET运行时(如果.NET ...

  2. ASP.NET (HttpModule,HttpHandler)

    asp.net 事件模型机制 ----------------------- 一 客户的请求页面由aspnet_isapi.dll这个动态连接库来处理,把请求的aspx文件发送给CLR进行编译执行,然 ...

  3. ASP.NET三剑客 HttpApplication HttpModule HttpHandler 解析

    我们都知道,ASP.Net运行时环境中处理请求是通过一系列对象来完成的,包含HttpApplication,HttpModule, HttpHandler.之所以将这三个对象称之为ASP.NET三剑客 ...

  4. HttpModule HttpHandler HttpHandlerFactory 学习笔记

    1.HttpModule 最常见的是使用HttpModule来做页面权限控制. 在新建类库添加如下代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ...

  5. ASP.NET 管道事件与HttpModule, HttpHandler简单理解

    BeginRequest 指示请求处理开始 AuthenticateRequest 封装请求身份验证过程 AuthorizeRequest 封装检查是否能利用以前缓存的输出页面处理请求的过程 Reso ...

  6. httphandler和httpmodule的区别

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

  7. HttpHandler与HttpModule及实现文件下载

    HttpHandler:处理请求(Request)的信息和发送响应(Response).HttpModule:通过Http Module向Http请求输出流中写入文字,httpmodule先执行 它们 ...

  8. ASP.NET内部原理(HttpHandler和HttpModule)

    [IT168 技术文档]在以前的ASP时候,当请求一个*.asp页面文件的时候,这个HTTP请求首先会被一个名为 inetinfo.exe进程所截获,这个进程实际上就是www服务.截获之后它会将这个请 ...

  9. 【N年前的文章脑补:HttpHandler HttpModule入门篇】

    HttpHandler HttpModule入门篇 ASP.Net处理Http Request时,使用Pipeline(管道)方式,由各个HttpModule对请求进行处理,然后到达 HttpHand ...

随机推荐

  1. ios开发之网络php

    接着前面的学习,几天上午学习了数据库网络值php用户的注册与登录,感觉代码与ios上的oc太相似了,因此学习下来没什么障碍了,下面是代码: 首先是javascript.html文件中: <!DO ...

  2. MySQL数据库6 -查询基础,简单查询,条件查询,对查询结果排序

    一.SELECT语句 SELECT COL1,COL2,....COLn FROM TABLE1,TABLE2,....TABLEn [WHERE CONDITIONS] -- 查询条件 [GROUP ...

  3. Ubuntu下libpcap安装

    1.首先按下面的博客教程下载和安装四个软件包: 点击打开链接 2.这四个软件都安装好之后按下面教程新建Makefile文件和test.c文件: 点击打开链接 Makefie: all: test.c ...

  4. Drools环境搭建(转)

    Eclipse3.5安装Drools5.2.0.Final插件 到Drools下载页面(现在是http://www.jboss.org/drools/downloads.html) -下载并解压Dro ...

  5. C#通过反射进行枚举描述相关操作

    C#可以通过反射,来获取枚举的描述信息或通过描述信息获取到指定类型的枚举 /// <summary> /// 获取枚举描述 /// </summary> /// <par ...

  6. AI第二次作业

    2.9  设有如下语句,请用相应的谓词公式分别把它们表示出来: (1)有的人喜欢梅花,有的人喜欢菊花,有的人既喜欢梅花又喜欢菊花.      解:设 P(x): x是人      L(x,y): x喜 ...

  7. C#中隐藏(new)、方法重写(override)、重载(overload)的区别

    转自:http://www.cnblogs.com/glife/archive/2009/12/28/1633947.html 重载.重写和隐藏的定义: 重载:public string ToStri ...

  8. linux查看一条命令的执行结果是1还是0

    echo $? 0为成功 其他为失败

  9. IOS 关于开发的APP跳转第三方应用的心得

    昨天晚上自己做了个APP,想做个功能可以去跳转到手机上的微博,微信.找了好些资料,下面总结下自己的心得. 跳转的核心代码如下: if ([[UIApplication sharedApplicatio ...

  10. IOS中延迟执行的几种方法

    前几天去国美在线面试,就遇到了上面的问题,当时是笔试,只写出来了第一种方法,现在整理了一下. //1.performSelector方法:在当前线程中执行的方法,使用默认模式,并延迟执行@select ...