ASP.NET Lab

The Best Web, The Best Future

博客园 首页 新随笔 订阅 管理

本文描述应用程序生命周期的摘要信息,列表了重要的生命周期事件并描述如何编写合适的处理代码。在 ASP.NET 中,部分处理步骤只在应用程序初始化并处理请求时才会发生。另外,对来自浏览器的 ASP.NET 请求而提供服务仅是 Web 服务器架构的一小部分。但是了解应用程序生命周期对于自定义适合生命周期中各种情景处理的代码时是重要的。

应用程序生命周期的一般情况

下表说明了 ASP.NET 应用程序生命周期中的各种情景。

情景描述

用户使用 Web 浏览器发送对应用资源的请求。

ASP.NET 应用程序的生命周期始于发送到 Web 服务器(ASP.NET 通常使用 IIS 做为服务器)的请求。ASP.NET 是 Web 服务器的一个 ISAPI 扩展。当 Web 服务器接收请求后会分析被请求文件扩展名,检测该使用哪种 ISAPI 扩展来处理,然后将请求传递给相应的 ISAPI 扩展。由 ASP.NET 处理的文件扩展名包括有 .aspx,.ascx,.ashx,和 .asmx。

注意:如果上述扩展名未被映射到 ASP.NET,那么 ASP.NET 就无法接收请求。了解使用 ASP.NET 授权的应用程序是重要的。比如,.htm 文件通常不会映射到 ASP.NET,ASP.NET 也不对 .html 文件的请求进行验证或处理。因此,即使对于只包含静态内容的文件,允许将扩展名改成映射成 ASP.NET 处理类型的 .aspx 来要求 ASP.NET 进行处理。

注意:如果为拥有特殊扩展名的文件创建了自定义处理器,则需要将该扩展名映射到 IIS 中的 ASP.NET 扩展并在应用程序 Web.config 文件中注册自定义处理器。

ASP.NET 接收应用程序的第一个请求。

当 ASP.NET 接收到应用程序的第一个资源请求时,名为 ApplicationManager 的类对象会创建应用程序域空间。应用程序域空间为应用程序提供独立的全局变量,允许任何一个应用程序自由销毁。应用程序域空间会创建 HostingEnvironment 实例,提供应用程序相关信息(如存储应用程序的目录名)的访问。

相关内容如图所示:

应用程序运行方式

ASP.NET 会编译应用程序中被请求的最顶层项目,包括 App_Code 目录中的应用程序代码。

ASP.NET 为每个请求都创建核心处理对象。

在创建应用程序域空间并实例化 HostingEnvironment 对象之后,ASP.NET 会创建并初始化核心处理对象(如 HttpContextHttpRequest,以及 HttpResponse)。HttpContext 类包含指派给当前应用请求的相关对象,如 HttpRequestHttpResponseHttpRequest 对象包含当前请求的相关信息,包括 Cookies 和浏览器信息。HttpResponse 对象包含发送到客户端的回应内容,包括所有被呈现的输出内容和 Cookies。

为请求指派 HttpApplication 对象。

应用程序所有核心对象都初始化完成之后,应用程序就开始创建 HttpApplication 实例。如果应用程序使用了 Global.asax 文件,ASP.NET 还会为 Global.asax 创建 HttpApplication 的派生实例,并替代默认实例来重载应用程序。

注意:第一次请求或处理页面时,会创建新的 HttpApplication 实例。但在需要性能最大化的时候,HttpApplication 实例可以在多个请求中重复使用。

在创建 HttpApplication 实例时会创建所有已配置模块。应用程序配置为实例后,ASP.NET 会创建 SessionStateModule 模型。在所有已配置模块创建完毕后会调用 HttpApplicationInit 方法。

相关内容如图所示:

应用程序组成环境

请求 HttpApplication 的管道处理。

下列事件在处理请求时由 HttpApplication 执行。开发者在扩展 HttpApplication 时应该注意对这些事件的处理。

  1. 对请求的内容进行验证,分析由浏览器发送的信息并检测是否含有潜在的不安全标记。
  2. 完成 URL 映射,映射 Web.config 文件 UrlMappingsSection 元素中所有已配置 URL 映射。
  3. 引发 BeginRequest 事件。
  4. 引发 AuthenticateRequest 事件。
  5. 引发 PostAuthenticateRequest 事件。
  6. 引发 AuthorizeRequest 事件。
  7. 引发 PostAuthorizeRequest 事件。
  8. 引发 ResolveRequestCache 事件。
  9. 引发 PostResolveRequestCache 事件。
  10. 可使用实现 IHttpHandler 接口的自定义类处理具有特定扩展名的资源(必须经过应用程序的配置文件进行映射),ASP.NET 会在创建 Page 派生实例之前对其进行编译。
  11. 引发 PostMapRequestHandler 事件。
  12. 引发 AcquireRequestState 事件。
  13. 引发 PostAcquireRequestState 事件。
  14. 引发 PreRequestHandlerExecute 事件。
  15. 使用合适的 IHttpHandler 对象为请求调用 ProcessRequest 方法(或异步版本的 BeginProcessRequest 方法)。比如,页面请求则由当前页面的实例进行处理。
  16. 引发 PostRequestHandlerExecute 事件。
  17. 引发 ReleaseRequestState 事件。
  18. 引发 PostReleaseRequestState 事件。
  19. 如果定义了 Filter 属性则对回应内容进行过滤。
  20. 引发 UpdateRequestCache 事件。
  21. 引发 PostUpdateRequestCache 事件。
  22. 引发 EndRequest 事件。

生命周期事件和 Global.asax 文件

应用程序生命周期中引发的所有事件可由开发者通过特定方法的重载进行处理。这需要在应用程序根目录创建 Global.asax 文件。

创建 Global.asax 文件后,ASP.NET 会将它编译进 HttpApplication 的继承类,并使用这个类重载应用程序。

HttpApplication 实例的进程每次只处理一个请求。因此,访问应用程序的非静态成员不再需要锁定与解锁,简化了应用程序事件处理过程。但仍然可以把具体数据存储在应用程序的非静态成员中。比如,在 Global.asax 文件中自定义属性并赋值。

ASP.NET 自动将应用程序事件绑定到 Global.asax 文件的处理过程,处理过程通常以“Application_事件”的格式命名(如 Application_BeginRequest)。这与 ASP.NET 页面方法自动与页面事件(如 Page_Load)绑定类似。

HttpApplication 对象的 Application_StartApplication_End 方法属于不允许重载的特殊方法。

下表列出应用程序生命周期内使用的各种事件和函数。实际上还有更多内容未被列出,因为通常情况下并不需要使用。

事件或方法描述

Application_Start

第一次请求 ASP.NET 应用程序资源时被调用。Application_Start 方法在应用程序生命周期内只调用一次。可以用该方法完成部分启动任务,如把数据读入高速缓存或初始化静态值。

应用程序启动时只允许设置静态数据。注意不要为任何实例化数据赋值,因为它们仅在第一个被创建的 HttpApplication 实例中有效。

Application_事件

在应用程序生命周期内的合适时间被引发,跟本文前面部分应用程序生命周期表里列出的情况一样。

Application_Error 可以在应用程序生存周期的任何阶段被引发。

Application_EndRequest 是唯一能够对于每个请求都确保能够引发的事件,因为请求过程通常比较短。比如,两个模块同时处理 Application_BeginRequest 事件,那么第一个模块就会产生并抛出一个异常对象,因为 Application_BeginRequest 事件不允许第二个模块的调用。但 Application_EndRequest 方法始终允许应用程序清理过期资源。

HttpApplication.Init

当所有模块创建完成后,分别由 HttpApplication 类的每个实例进行且只能进行一次调用。

Dispose

在销毁应用程序实例时被调用。用于手动释放非托管资源。

Application_End

每个应用程序实例被释放之前被调用,且只能调用一次。

HTTP 模块

ASP.NET 应用程序生命周期可以通过 IHttpModule 接口进行扩展。ASP.NET 包括若干实现 IHttpModule 接口的类,如 SessionStateModule 等等。也可以用 IHttpModule 接口实现自定义类。

在应用程序中添加模块后,模块本身也能够引发事件。应用程序能够在 Global.asax 文件中预订这些事件,通常使用“模块名_事件名”格式命名。比如,创建名为 FormsAuthentication_Authenticate 的处理器来处理由 FormsAuthenticationModule 对象引发的 Authenticate 事件。

ASP.NET 默认时启用 SessionStateModule 类。所有会话事件都自动以“Session_事件”格式命名(如 Session_Start)。每创建一个新的会话对象都会引发 SessionStart 事件。

posted on 2006-12-06 18:20  Laeb  阅读(1031)  评论(0编辑  收藏  举报