• 深入理解ASP.NET中的管线(Pipeline)
  • 李奇 发表于 2015/12/29 13:48:00 | 分类标签: ASP.NET 管线 Pipeline
  • 管线(Pipeline)这个词也是很有点意思,这个词也形象地说明了每个Asp.net请求的处理过程: 请求是在一个管道中,要经过一系列的过程点,这些过程点连接起来也就形成一条线。 以上是我对于这个词的理解,如果有误,恳请给予指正。 这些一系列的过程点,其实就是由HttpApplication引发的一系列事件,通常可以由HttpModule来订阅, 也可以在Global.asax中订阅,这一系列的事件也就构成了一次请求的生命周期。

    事件模式,也就是观察者模式。根据【C# 3.0 设计模式】一书中的定义:“ 观察者模式定义了对象之间的一种联系,使得当一个对象改变状态时,所有其它的对象都可以相应地被通知到。" Asp.net的管线设计正是采用了这种方式, 在这个设计模式中,观察者就是许多HttpModule对象,被观察的对象就是每个”请求“,它的状态是由HttpApplication 控制,用于描述当前请求的处理阶段,HttpApplication会根据一个特定的顺序修改这个状态,并在每个状态改变后引发相应的事件。 Asp.net会为每个请求分配一个HttpApplication对象来引发这些事件,因此可以让一大批观察者了解每个请求的状态, 每个观察者也可以在感兴趣的时候修改请求的一些数据。 这些与请求相关的数据的也就是我上篇博客中提到的HttpRequest, HttpResponse。 正是由于引入了事件机制,Asp.net框架也有了极强的扩展能力。再来看看管线处理请求的过程,我将直接引用MSDN中的原文【IIS 5.0 和 6.0 的 ASP.NET 应用程序生命周期概述】中的片段。

    在处理该请求时将由 HttpApplication 类执行以下事件。 希望扩展 HttpApplication 类的开发人员尤其需要注意这些事件。
    1. 对请求进行验证,将检查浏览器发送的信息,并确定其是否包含潜在恶意标记。 有关更多信息,请参见 ValidateRequest 和脚本侵入概述。
    2. 如果已在 Web.config 文件的 UrlMappingsSection 节中配置了任何 URL,则执行 URL 映射。
    3. 引发 BeginRequest 事件。
    4. 引发 AuthenticateRequest 事件。
    5. 引发 PostAuthenticateRequest 事件。
    6. 引发 AuthorizeRequest 事件。
    7. 引发 PostAuthorizeRequest 事件。
    8. 引发 ResolveRequestCache 事件。
    9. 引发 PostResolveRequestCache 事件。
    10. 根据所请求资源的文件扩展名(在应用程序的配置文件中映射),选择实现 IHttpHandler 的类,对请求进行处理。 如果该请求针对从 Page 类派生的对象(页),并且需要对该页进行编译,则 ASP.NET 会在创建该页的实例之前对其进行编译。
    11. 引发 PostMapRequestHandler 事件。
    12. 引发 AcquireRequestState 事件。
    13. 引发 PostAcquireRequestState 事件。
    14. 引发 PreRequestHandlerExecute 事件。
    15. 为该请求调用合适的 IHttpHandler 类的 ProcessRequest 方法(或异步版 IHttpAsyncHandler.BeginProcessRequest)。 例如,如果该请求针对某页,则当前的页实例将处理该请求。 
    16. 引发 PostRequestHandlerExecute 事件。
    17. 引发 ReleaseRequestState 事件。
    18. 引发 PostReleaseRequestState 事件。
    19. 如果定义了 Filter 属性,则执行响应筛选。
    20. 引发 UpdateRequestCache 事件。
    21. 引发 PostUpdateRequestCache 事件。
    22. 引发 EndRequest 事件。
    23. 引发 PreSendRequestHeaders 事件。
    24. 引发 PreSendRequestContent 事件。

    如果是IIS7,第10个事件也就是MapRequestHandler事件,而且在EndRequest 事件前,还增加了另二个事件:LogRequest 和 PostLogRequest 事件。
    只有当应用程序在 IIS 7.0 集成模式下运行,并且与 .NET Framework 3.0 或更高版本一起运行时,才会支持 MapRequestHandler、LogRequest 和 PostLogRequest 事件。

    这里要补充一下:从BeginRequest开始的事件,并不是每个事件都会被触发,因为在整个处理过程中,随时可以调用Response.End() 或者有未处理的异常发生而提前结束整个过程。在那些"知名"的事件中,也只有EndRequest事件是肯定会触发的, (部分Module的)BeginRequest有可能也不会被触发。

    对于这些管线事件,我只想提醒2个非常重要的地方:
    1. 每个请求都将会映射到一个HttpHandler,通常也是处理请求的主要对象。
    2. HttpModule可以任意订阅这些事件,在事件处理器中也可以参与修改请求的操作。
    这2点也决定了HttpHandler和HttpModule的工作方式。
  • 请您注意

    ·自觉遵守:爱国、守法、自律、真实、文明的原则

    ·尊重网上道德,遵守《全国人大常委会关于维护互联网安全的决定》及中华人民共和国其他各项有关法律法规

    ·严禁发表危害国家安全,破坏民族团结、国家宗教政策和社会稳定,含侮辱、诽谤、教唆、淫秽等内容的作品

    ·承担一切因您的行为而直接或间接导致的民事或刑事法律责任

    ·您在编程中国社区新闻评论发表的作品,本网站有权在网站内保留、转载、引用或者删除

    ·参与本评论即表明您已经阅读并接受上述条款

  • 感谢本文作者
  • 作者头像
  • 昵称:李奇
  • 加入时间:2013/6/13 0:00:00
  • TA的签名
  • 这家伙很懒,虾米都没写
  • +进入TA的空间
  • 以下内容也很赞哦
分享按钮