Hard
随笔- 17  文章- 2  评论- 11 
博客园  首页  新随笔  联系  管理  订阅 订阅
2009年7月30日
ASP.NET 页生命周期

      ASP.NET 页运行时,此页将经历一个生命周期,在生命周期中将执行一系列处理步骤。这些步骤包括初始化、实例化控件、还原和维护状态、运行事件处理程序代码以及进行呈现。了解页生命周期非常重要,因为这样做我们就能在生命周期的合适阶段编写代码,以达到预期效果。此外,如果要开发自定义控件,就必须熟悉页生命周期,以便正确进行控件初始化,使用视图状态数据填充控件属性以及运行任何控件行为代码。(控件的生命周期基于页的生命周期,但是页引发的控件事件比单独的 ASP.NET 页中可用的事件多。)
      一般来说,页要经历以下的各个阶段。除了页生命周期阶段以外,在请求前后还存在应用程序阶段,但是这些阶段并不特定于页。可以参考:

  • 页请求

        页请求发生在页生命周期开始之前。用户请求页时,ASP.NET 将确定是否需要分析和编译页(从而开始页的生命周期),或者是否可以在不运行页的情况下发送页的缓存版本以进行响应。

  • 开始

       在开始阶段,将设置页属性,如 Request 和 Response。在此阶段,页还将确定请求是回发请求还是新请求,并设置 IsPostBack 属性。此外,在开始阶段期间,还将设置页的 UICulture 属性。

      页初始化
       页初始化期间,可以使用页中的控件,并将设置每个控件的 UniqueID 属性。此外,任何主题都将应用于页。如果当前请求是回发请求,则回发数据尚未加载,并且控件属性值尚未还原为视图状态中的值。

      加载
       加载期间,如果当前请求是回发请求,则将使用从视图状态和控件状态恢复的信息加载控件属性。

      验证
       在验证期间,将调用所有验证程序控件的 Validate 方法,此方法将设置各个验证程序控件和页的 IsValid 属性。
      
      回发事件处理
       如果请求是回发请求,则将调用所有事件处理程序。

      呈现
      在呈现之前,会针对该页和所有控件保存视图状态。在呈现阶段中,页会针对每个控件调用 Render 方法,它会提供一个文本编写器,用于将控件的输出写入页的 Response 属性的 OutputStream 中。

      卸载
      完全呈现页并已将页发送至客户端、准备丢弃该页后,将调用卸载。此时,将卸载页属性(如 Response 和 Request)并执行清理。

       

      在页生命周期的每个阶段中,页将引发可运行代码进行处理的事件。对于控件事件,通过以声明方式使用属性(如 onclick)或以使用代码的方式,均可将事件处理程序绑定到事件。

      页还支持自动事件连接,即,ASP.NET 将查找具有特定名称的方法,并在引发了特定事件时自动运行这些方法。如果 @ Page 指令的 AutoEventWireup 属性设置为 true(或者未定义该属性,因为该属性默认为 true),页事件将自动绑定至使用 Page_事件的命名约定的方法(如 Page_Load 和 Page_Init)。

   最常用的页生命周期事件    
       PreInit

        使用该事件来执行下列操作:

  • 检查 IsPostBack 属性来确定是不是第一次处理该页。

  • 创建或重新创建动态控件。

  • 动态设置主控页。

  • 动态设置 Theme 属性。

  • 读取或设置配置文件属性值。

       Init

      在所有控件都已初始化且已应用所有外观设置后引发。使用该事件来读取或初始化控件属性。


      InitComplete 
      由 Page 对象引发。使用该事件来处理要求先完成所有初始化工作的任务。
      
      PreLoad
      如果需要在 Load 事件之前对页或控件执行处理,请使用该事件。

      在 Page 引发该事件后,它会为自身和所有控件加载视图状态,然后会处理 Request 实例包括的任何回发数据。


      Load
      Page 在 Page 上调用 OnLoad 事件方法,然后以递归方式对每个子控件执行相同操作,如此循环往复,直到加载完本页和所有控件为止。使用 OnLoad 事件方法来设置控件中的属性并建立数据库连接。
      
      控件事件
      使用这些事件来处理特定控件事件,如 Button 控件的 Click 事件或 TextBox 控件的 TextChanged 事件。

      LoadComplete
      对需要加载页上的所有其他控件的任务使用该事件。

      PreRender
      在该事件发生前:

  • Page 对象会针对每个控件和页调用 EnsureChildControls。

  • 设置了 DataSourceID 属性的每个数据绑定控件会调用 DataBind 方法。

      页上的每个控件都会发生 PreRender 事件。使用该事件对页或其控件的内容进行最后更改。


      SaveStateComplete
      在该事件发生前,已针对页和所有控件保存了 ViewState。将忽略此时对页或控件进行的任何更改。

使用该事件执行满足以下条件的任务:要求已经保存了视图状态,但未对控件进行任何更改。

      Render
      这不是事件;在处理的这个阶段,Page 对象会在每个控件上调用此方法。所有 ASP.NET Web 服务器控件都有一个用于写出发送给浏览器的控件标记的 Render 方法。

      如果创建自定义控件,通常要覆盖此方法以输出控件的标记。不过,如果自定义控件只合并标准的 ASP.NET Web 服务器控件,不合并自定义标记,则不需要覆盖 Render 方法。

      用户控件(.ascx 文件)自动合并呈现,因此不需要在代码中显式呈现该控件。


      Unload
      该事件首先针对每个控件发生,继而针对该页发生。在控件中,使用该事件对特定控件执行最后清理,如关闭控件特定数据库连接。

      对于页自身,使用该事件来执行最后清理工作,如:关闭打开的文件和数据库连接,或完成日志记录或其他请求特定任务。

 

 


 

 

 

 

posted @ 2009-07-30 14:00 Hard 阅读(65) 评论(0) 编辑
IIS 7.0 的 ASP.NET 应用程序生命周期

      ASP.NET 应用程序的生命周期以浏览器向 Web 服务器发送请求为起点。 有关IIS的工作原理,博客园里比较经典的文章:http://www.cnblogs.com/szhy222/archive/2008/07/14/1242576.html。IIS 7.0 集成模式下的请求会经历几个阶段,类似于在 IIS 6.0 中对 ASP.NET 资源的请求所经历的阶段。但是,在 IIS 7.0 中,这些阶段包含多个额外的应用程序事件,如 MapRequestHandler、LogRequest 和 PostLogRequest 事件。

      IIS 7.0 和 IIS 6.0 的处理阶段之间的主要区别在于 ASP.NET 如何与 IIS 服务器集成。在 IIS 6.0 中,有两个请求处理管道。一个管道用于本机代码 ISAPI 筛选器和扩展组件。另一个管道用于托管代码应用程序组件,如 ASP.NET。在 IIS 7.0 中,ASP.NET 运行库与 Web 服务器集成,这样就有了一个针对所有请求的统一的请求处理管道。


在 IIS 7.0 集成模式下运行的 ASP.NET 应用程序生命周期的各个阶段

              发出一个对应用程序的请求

  •       ASP.NET应用程序的生命周期以浏览器向Web服务器发送请求为起点。 在 IIS 7.0 经典模式下以及在 IIS 6.0 中,ASP.NET 请求管道与 Web 服务器管道分离。模块仅应用于路由到 ASP.NET ISAPI 扩展的请求。如果请求的资源类型的文件扩展名未显式映射到 ASP.NET,则不会为该请求调用 ASP.NET 功能,因为 ASP.NET 运行库没有处理该请求。

          而在 IIS 7.0 集成模式下,由一个统一的管道处理所有请求。当集成管道收到请求时,该请求将经历所有请求共有的一些阶段。这些阶段由 RequestNotification 枚举表示。所有请求都可以配置为使用 ASP.NET 功能,因为该功能封装在可以访问请求管道的托管代码模块中。例如,即使 .htm 文件扩展名未显式映射到 ASP.NET,对 HTML 页的请求仍会调用 ASP.NET 模块。这使我们能对所有资源使用 ASP.NET 身份验证和授权。

          统一管道接收对应用程序的第一个请求
  •       

          当统一管道接收对应用程序中的任何资源的第一个请求时,将为 ApplicationManager 类创建一个实例,该实例就是处理请求的应用程序域。应用程序域提供了应用程序之间全局变量的分离,并且使每个应用程序能够单独卸载。在应用程序域中,将为 HostingEnvironment 类创建一个实例,该实例提供对有关应用程序的信息(如存储该应用程序的文件夹的名称)的访问。

          在第一个请求期间,如果需要,将对应用程序中的顶级项进行编译,其中包括 App_Code 文件夹中的应用程序代码(可在 App_Code 文件夹中包含自定义模块和处理程序)。


          为每个请求创建响应对象
  •       

          在创建了应用程序域并对 HostingEnvironment 对象进行了实例化之后,将创建并初始化应用程序对象,如 HttpContext、HttpRequest 和 HttpResponse。HttpContext 类包含特定于当前应用程序请求的对象,如 HttpRequest 和 HttpResponse 对象。HttpRequest 对象包含有关当前请求的信息,包括 Cookie 和浏览器信息。HttpResponse 对象包含发送到客户端的响应,其中包括所有呈现的输出和 Cookie。


          将HttpApplication对象分配给请求
  •       初始化所有应用程序对象之后,将通过创建 HttpApplication 类的实例来启动应用程序。如果应用程序有 Global.asax 文件,则 ASP.NET 会创建从 HttpApplication 类派生的 Global.aspx 类的实例。然后使用该派生类来表示应用程序。 

              第一次在应用程序中请求 ASP.NET 页或进程时,将创建 HttpApplication 类的一个新实例。不过,为了尽可能提高性能,可对多个请求重复使用 HttpApplication 实例。

   
      由HttpApplication管线处理请求

  •       在处理请求时,HttpApplication 类会执行下列任务。
    1. 对请求进行验证,将检查浏览器发送的信息,并确定其是否包含潜在恶意标记。

    2. 如果已在 Web.config 文件的 UrlMappingsSection 节中配置了任何 URL,则执行 URL 映射。

    3. 引发 BeginRequest 事件。

    4. 引发 AuthenticateRequest 事件。

    5. 引发 PostAuthenticateRequest 事件。

    6. 引发 AuthorizeRequest 事件。

    7. 引发 PostAuthorizeRequest 事件。

    8. 引发 ResolveRequestCache 事件。

    9. 引发 PostResolveRequestCache 事件。

    10. 引发 MapRequestHandler 事件。将根据所请求资源的文件扩展名,选择相应的处理程序。处理程序可以是本机代码模块,如 IIS 7.0 StaticFileModule,也可以是托管代码模块,如 PageHandlerFactory 类(它处理 .aspx 文件)。

    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. 引发 LogRequest 事件。

    23. 引发 PostLogRequest 事件。

    24. 引发 EndRequest 事件。

    25. 引发 PreSendRequestHeaders 事件。

    26. 引发 PreSendRequestContent 事件。

posted @ 2009-07-30 10:07 Hard 阅读(128) 评论(0) 编辑
Copyright ©2012 Hard