zoukankan      html  css  js  c++  java
  • ASP.NET拾遗:ASP.NET页面生命周期

           ASP.NET编程模型中ASP.NET页面生命周期是指什么呢?它包括什么呢?ASP.NET编程模型之ASP.NET页面生命周期具体的过程有哪些呢?下面就开始我们的讲解吧:

          ASP.NET 页运行时,此页将经历一个生命周期,在生命周期中将执行一系列处理步骤。这些步骤包括初始化、实例化控件、还原和维护状态、运行事件处理程序代码以及进行 呈现。了解页的生命周期非常重要,这样就能在合适的生命周期阶段编写代码,以达到预期效果。此外,如果开发自定义控件,则必须熟悉页生命周期,从而正确地 初始化控件,使用视图状态数据填充控件属性以及运行所有控件行为逻辑。

         ASP.NET编程模型之页面生命周期执行一系列步骤:页面的初始化、实例化控件、还原和维护状态、运行事件处理程序代码、呈现。为了在合适的阶段 执行所需的代码,所以要对页面生命周期非常熟悉。在页生命周期的各个阶段,页面会逐个引发定义的事件,通过对代码开发,在页面的生命事件中执行我们所需要 的程序
    页生命周期阶段

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

    2、ASP.NET页面生命周期之启动[Start]:设置页属性,如:HttpContext、 Request 和 Response以及其他属性;在此阶段,页面需要确定是回发请求还是新请求,并设置IsPostBack属性;设置页面的UICulture属性。

    3、 ASP.NET页面生命周期之页面初始化[initialization]:加载所有主题;控件生成,并设置UniqueID;如果需要,还会向页应用于母版页和主题。 如果当前请求是回发请求,则回发数据尚未加载,并且控件属性值尚未还原为视图状态中的值。

    注:ViewState、ControlState中的值还未加载至控件;如果页面是回发,则回发数据也还未加载;故此时控件可以访问,但值可能出错。

    4、ASP.NET页面生命周期之加载[Load]:如果当前请求是回发请求,则为控件加载ViewState和ControlState中的值。

    5、ASP.NET页面生命周期之回发事件处理[Postback event handling]:如果请求是回发请求,则调用所有事件处理程序。之后,将调用所有验证程序控件的Validate方法,此方法将设置验证程序控件和页的IsValid属性。

    6、ASP.NET页面生命周期之呈现[Render]:首先对该页和所有控件进行保存视图状态,然后对每个控件调用Render方法,它会提供一个文本编写器,用于将控件的输入写入页的Response属性的OutputStream中。

    7、ASP.NET页面生命周期之卸载[Unload]:完成呈现,并已将页发送至客户端、准备丢弃该页后,调用卸载。将卸载属性如:Response和Request等等。

    下面是ASP.NET编程模型中ASP.NET页面生命周期示图

        ASP.NET编程模型中ASP.NET页面生命周期的简单架构介绍就向你介绍到这里,之后我们会继续详细介绍ASP.NET编程模型之ASP.NET页面生命周期的相关内容。

        页面框架通过如下过程处理aspx文件请求:
        1:解析aspx文件,并创建一个控件树;
        2:使用控件树动态实现一个继承自Page类的类或者控件 ;
        3:动态编译类;
        4:缓存编译类,以备后用;
        5:动态创建一个编译类的实例。页面开始启动生命期,在这个过程中,页面将通过生命周期的不同阶段;=========================================================
    页面经历了如下阶段【其中一些阶段标记为仅仅回传,是说只有在被回传到服务器时,页面才经历这些阶段】:

    01:页面首先从QueryString或者Request对象的Form集合中获得回传数据。

    02:页面检测回传数据集合(NameValueCollection,Form或者QueryString)是否包含一个键为_CallBackId的项。如 果存在,那么设置其Boolean属性IsCallBack为True,以便通过AspNet客户端回调机制,标明页面已经回传到服务器。

    03:预初始化(PreInit)

    在启动阶段完成之后、初始化阶段开始之前引发。

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

    • 检查 IsPostBack 属性来确定是不是第一次处理该页。 此时还设置了 IsCallbackIsCrossPagePostBack 属性。

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

    • 动态设置主控页。

    • 动态设置 Theme 属性。

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

    注意 如果请求是回发请求,则控件的值尚未从视图状态还原。如果在此阶段设置控件属性,则其值可能会在下一事件中被覆盖。

    04:初始化(Init)

    在所有控件都已初始化且已应用所有外观设置后引发。 各个控件的 Init 事件在页的 Init 事件之前发生。

    使用该事件来读取或初始化控件属性。
    在页面生命周期的初始化阶段执行以下操作
    a:递归初始化Controls集合中的控件。初始化包括设置这些控件的属性,
    例如:Page,Id和NameContainer等
    b:递归应用控件皮肤
    c:调用OnInit方法以引发自身的Init事件,接着递归调用子控件的OnInit方法来引发它们的Init事件
    d:调用自身的TrackViewState方法来启动自身的视图状态跟踪,接着递归调用子控件
    的TrackViewState方法来启动它们的视图状态跟踪。

    05:完成初始化(InitComplete):

    在页的初始化阶段结束时引发。 Init 和 InitComplete 事件之间仅发生一个操作:开启对视图状态更改的跟踪。 视图状态跟踪使控件可以保留所有以编程方式添加到 ViewState集合的值。 在开启视图状态跟踪之前,所有添加到视图状态的值都会在回发期间丢失。 控件通常在引发其 Init 事件后立即开启视图状态跟踪。

    使用此事件对要在下一个回发后务必保留的视图状态进行更改。
    页面调用OnInitComplete方法来引发InitComplete事件。该事件标明了初始化阶段的结束。
    此时,页面Controls集合的所有控件都被初始化了。

    06:加载控件状态(Load Control State)[PostBack Only]:
    页面递归调用Control集合中控件的LoadControlState方法,这些控件已经调用了Page类
    的RegisterRequiresControlState方法,以使用它们的控件状态。

    07:加载视图状态(Load View State)[PostBack Only]:
    页面首先调用自身的LoadViewState方法,接着递归调用Controls集合控件的LoadViewState方法,以允许它们加载它们的已经保存的视图状态。

    08:加载回传数据(Load Post Data)[PostBack Only]:
    页面调用实现IPostBackDataHandler接口的控件的LoadPostData方法,并将回传数据传递给该方法。每个控件的LoadPostDate方法都必须访问回传数据,并据此更新相应的控件属性。
    例如:TextBox控件的LoadPostData方法将文本框的新值设置为TextBox控件的Text属性值。

    09:预加载(PreLoad):

    在页为自身和所有控件加载视图状态之后以及处理 Request 实例包括的回发数据之后引发。
    页面调用OnPreLoad方法以引发PreLoad事件。该事件表示页面生命周期将进入加载阶段。

    10:加载(Load):

    Page 对象对 Page 对象调用 OnLoad 方法,然后以递归方式对每个子控件执行相同操作,直到加载完本页和所有控件为止。 各个控件的 Load 事件在页的 Load 事件之后发生。

    使用 OnLoad 事件方法来设置控件中的属性并建立数据库连接。

    页面首先调用自身的OnLoad方法以引发自身的Load事件,接着递归调用Controls集合中控件的OnLoad方法以引发它们的Load事件。页面开发人员可以为Load事件注册回调,那么就可以通过编程将子控件添加到页面的Controls集合中。

    11:加载回传数据(Load Post Data)[PostBack Only Second Try]:
    页面调用控件的LoadPostBack方法。这些控件如果实现了IPostBackDataHandler接口,那么在加载阶段,它们已通过编程添加到Controls集合中。

    12:引发回传数据修改事件(Raise Post Data Changed Event)[PostBack Only]:
    页面调用控件的RaisePostDataChangeEvent方法,这些控件的LoadPostData方法返回true。
    RaisePostDataChangeEvent方法引发了回传数据修改事件。例如:当文本框的新值与旧值
    不同时,那么TextBox控件将引发该事件。

    13:引发回传事件(Raise PostBack Event)[PostBack Only]:
    页面调用控件的RaisePostEvent方法,这些控件相关的Html元素用于提交表单。例如,Button控件的相关Html元素将页面回传到服务器。控件的RaisePostBackEvent方法必须将回传事件映射到一个或多个服务器事件。例如,Button控件的RaisePostBackEvent方法将事件映射到了服务器端事件Command和Click上。

    14:完成加载(Load Complete):

    在事件处理阶段结束时引发。

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

    页面调用OnLoadComplete方法来引发LoadComplete事件,这表示所有加载活动,包括加载回传数据,以及引发回传数据修改事件,并以更新控件自身的活动都完成了。

    15:引发回调事件(Raise CallBack Event)(PostBack And CallBack Only):
    页面调用控件的RaiseCallBackEvent方法。该控件可使用AspNet客户端回调机制来允许客户端方法(例如JavaScript函数)调用服务器端方法,而无需将整个页面回传给服务器。
    RaiseCallBackEvent方法必须调用服务器端方法。如果页面的回传使用了客户端回调机制,那么页面将不会执行剩余的页面生命周期阶段。

    16:预呈现(PreRender):

    Page 对象创建呈现页所需的所有控件(包括组合控件的子控件)之后引发。 (为此,Page 对象会针对每个控件和页调用 EnsureChildControls。)

    Page 对象在 Page 对象上调用 PreRender 事件,然后以递归方式对每个子控件执行相同操作。 各个控件的 PreRender 事件在页的 PreRender 事件之后发生。

    在呈现阶段开始之前,使用该事件对页或其控件的内容进行最后更改。

    在页面生命周期这个阶段执行一下操作。
    a:调用EnsureChildControls方法来确保在页面进入呈现阶段之前,创建其子控件。
    b:调用自身的OnPreRender方法来引发PreRender事件。
    c:递归调用Controls集合中控件的OnPreRender方法,以引发它们的PreRender事件。

    17:预呈现完成(PreRender Complete):

    在设置了 DataSourceID 属性的每个数据绑定控件调用其 DataBind 方法之后引发。 有关更多信息,请参见本主题后面的数据绑定控件的数据绑定事件

    页面调用OnPrerenderComplete方法来引发PreRenderComplete事件,这表示所有预呈现活动完成了。

    18:保存控件状态(Save Control State):
    页面递归调用Controls集合中控件的SaveControlState方法。这些控件已经调用了Page类的RegisterRequiresControlState方法来保存它们的控件状态。

    19:保存视图状态(Save View State):
    页面首先调用自身的SaveViewState方法,然后调用Controls集合中的SaveViewState方法,以允许它们来保存其视图状态。

    20:保存状态完成(Save View Complete):
    页面调用OnSaveStateComplete方法以引发SaveStateComplete事件,这表示所有状态保存活动都完成了。

    21:呈现:

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

    如果创建自定义控件,通常要覆盖此方法以输出控件的标记。 不过,如果自定义控件只合并标准的 ASP.NET Web 服务器控件,不合并自定义标记,则不需要覆盖 Render 方法。有关更多信息,请参见开发自定义 ASP.NET 服务器控件

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

    在页面生命周期的这个阶段执行一下操作。
    a:创建一个HtmlTextWriter类实例,该实例封装了输出响应流
    b:调用RenderCOntrol方法,并将HtmlTextWriter实例传递给该方法。
    RenderControl方法递归调用子控件的RenderControl方法,以便允许每个控件能够呈现其
    Html标记文本。子控件的Html标记文本组成了最终发送给客户端浏览器的Html标记文本。

    其他页面生命周期注意事项

    各个 ASP.NET 服务器控件都有自己的生命周期,该生命周期与页生命周期类似。 例如,控件的 InitLoad 事件在相应的页事件期间发生。

    虽然 InitLoad 都在每个控件上以递归方式发生,但它们的发生顺序相反。 每个子控件的 Init 事件(还有 Unload 事件)在为其容器引发相应的事件之前发生(由下到上)。但是,容器的 Load 事件是在其子控件的 Load 事件之前发生(由上到下)。

    当您创建从 Page 类继承的类时,除了可以处理由页引发的事件以外,还可以重写页的基类中的方法。 例如,可以覆盖页的 InitializeCulture 方法,以便动态设置区域性信息。 注意,在使用 Page_事件 语法创建事件处理程序时,将隐式调用基实现,因此无需在方法中调用它。 例如,无论是否创建 Page_Load 方法,始终都会调用页基类的 OnLoad 方法。 但是,如果使用 override 关键字(在 Visual Basic 中为 Overrides)覆盖页的 OnLoad 方法,则必须显式调用基方法。 例如,如果在页中覆盖 OnLoad 方法,则必须调用base.Load(在 Visual Basic 中为 MyBase.Load)以运行基实现。

    下图显示了 Page 类的一些最重要方法,您可以对其进行重写以便添加在页生命周期的特定点执行的代码。 (有关页方法和事件的完整列表,请参见 Page 类。)该图还演示这些方法如何与页事件和控件事件相关。 在该图中方法和事件的顺序为从上到下排列,在每行中为从左到右。

    添加的控件的追赶事件

    如果控件是在运行时动态创建的,或者是以声明方式在数据绑定控件的模板中创建的,它们的事件最初与页上的其他控件的事件并不同步。 例如,对于运行时添加的控件,InitLoad 事件在页生命周期中的发生时间可能要比以声明方式创建的控件的相同事件晚得多。 因此,从实例化那一刻起,动态添加的控件的事件就一直是在模板中的控件的事件之后发生,直到赶上该控件加入 Controls 集合时所对应事件为止。

    另附:

    参考:

    http://msdn.microsoft.com/zh-cn/library/ms178472.aspx

    http://developer.51cto.com/art/200908/141235.htm

    http://www.cnblogs.com/yellowapplemylove/archive/2011/04/19/2021601.html

    http://www.cnblogs.com/aion111/archive/2010/01/12/1645784.html

    http://www.cnblogs.com/cathsfz/archive/2006/11/19/564929.html

    http://www.cnblogs.com/zhongjie/archive/2011/06/12/2078939.html

  • 相关阅读:
    WCF 第十三章 可编程站点 为站点创建操作
    WCF 第十三章 可编程站点 所有都与URI相关
    WCF 第十二章 对等网 使用自定义绑定实现消息定向
    WCF 第十三章 可编程站点 使用WebOperationContext
    Using App.Config for user defined runtime parameters
    WCF 第十三章 可编程站点
    WCF 第十三章 可编程站点 使用AJAX和JSON进行网页编程
    WCF 第十二章 总结
    WCF 第十三章 可编程站点 使用WebGet和WebInvoke
    WCF 第十三章 可编程站点 URI和UriTemplates
  • 原文地址:https://www.cnblogs.com/wuji/p/2084463.html
Copyright © 2011-2022 走看看