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. C++中的文件读取结束

    while(cin>>N>>M) { } ok???

  2. vim笔记2

    用vim 快两年了 看过教程也不少,总的来说还是得自己多练习,当自己觉得有需要的时候,再添加功能.这里分享个看过的最好的教程,出自贴吧的某个朋友,写的很好 零 学会盲打 壹 配置文件先从最简开始,在 ...

  3. MVC 请求处理流程(二)

    [上一篇]中我们说到了对象AsyncControllerActionInvoker,在Controller的ExecuteCore方法中调用AsyncControllerActionInvoker对象 ...

  4. 推荐一个Android Studio很实用的插件android-butterknife-zelezny

    当你按钮很多,你又懒得写代码,虽然通过重写onClick比较方便,那么我们能不能连这个switch都省略掉呢? 答案是肯定的,下面这个插件就帮我们解决了这个问题! Android-butterknif ...

  5. CxImage图像库的使用 .

    http://blog.csdn.net/wangjie0377/article/details/7830405 CxImage图像库 CxImage下载地址:http://www.codeproje ...

  6. 新手码农浅谈观察者模式(java语言简单实现)

    一:什么是观察者模式: 官方定义:定义对象间一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. 举个例子,很多人都会订阅天气预报,当气象台获得明天的天气情况( ...

  7. LayaAir引擎——(九)

    var h = new Array(); var j = new Array(); var xbCursor = 0; function xbinit() { xbinitName(); xbRect ...

  8. 修改SharePoint 2013中item Created by 信息

    因为公司的系统有点小bug.额,要做点坏事,把系统没记上的东西偷偷补上去,但是item的created by变成了我(这怎么行,不能让别人知道我做了坏事,一定是隔壁小李干的! 懒得开visual st ...

  9. Linux手动释放缓存的方法

    Linux释放内存的命令:syncecho 1 > /proc/sys/vm/drop_caches drop_caches的值可以是0-3之间的数字,代表不同的含义:0:不释放(系统默认值)1 ...

  10. JavaScript和Java之间的关系

    今天来简单而又详细地说说JavaScript和Java的关系. 开门见山总结性一句话,它们之间的关系 = 雷锋和雷峰塔之间的关系,换句话说:它们之间没什么关系. 但往往有不少初学者甚至中级者认为它们之 ...