• Asp.net控件开发学习笔记(十)服务器控件生命周期


     

    在每一次httpRequestResponse周期asp.net web form都会执行一系列被称为控件生命周期的预定义过程


       
        在第一次通过
    HTTP Get方法获取到页面后,每一次向服务端进行HTTP POST回传都会分为以下几个步骤:

    1.      初始化控件树

    2.       将回传的ViewState进行解析

    3.      根据前几次的回传解析来为控件树中的每一个控件设置状态

    4.      处理回传数据

    5.      处理Page_Load事件

    6.      通过PostBack通知控件的数据变化,并在必要的情况下更新控件状态

    7.      执行基于控件状态改变的服务端事件(比如button的点击)

    8.      将控件状态持久化为ViewState

    9.      按照次序Render控件树中的每一个控件

    10. Dispose整个页面和控件树

     

       由上面的列表可以看出整个的用户Request和服务器Response的周期,首先是将状态解析并根据控件的状态来处理状态的改变,最后处理完后将这些Render回客户端,并将新的状态以ViewState的形式保存在客户端的hidden form中。

      页面生命周期对应事件

      在页面生命周期中,上面所说的每一个步骤都有一个对应的事件。这也就意味着你可以通过Override事件的执行方法来在页面周期中插入你自己的实现

      

    服务端事件

    页面生命周期

    描述

    Init

    Initialization

    初始化控件树

    LoadViewState

    Unpack ViewState

    ViewState里提取出状态信息

    LoadControlState

    Unpack control state

    从控件状态中提取出状态信息

    LoadPostData

    Handle form postback

    PostBack信息中更新控件状态信息

    Load

    Page_Load event

    执行Page_Load内的事件

    TrackViewState

    Track ViewState

    RaisePostDataChangedEvent

    Initialization for

    server-side events

    通知控件回传的状态将改变其值

    RaisePostBackEvent

    Execute server-side events

    对于指定的控件,如果状态信息改变,则引发该事件

    PreRender

    Render process

    让每个空间接收最新的状态信息

    SaveViewState

    Save ViewState

    保存ViewState

    SaveControlState

    Save control state

    Render

    Render process

    Render标准HTML,RenderHTML带有控件的状态信息

    Dispose

    Dispose of control tree

    释放资源

    服务器生命周期和HTTP GET以及HTTP POST

       System.Web.UI.Control基类定义了OnInit, OnLoad, OnPreRender, OnUnload,这四个事件可以被重写。而对于Dispose事件虽然Control也有定义,但并没有相应的OnDispose方法来引发事件,如果需要Dispose事件,需要实现IDispose接口。

       在通常情况下,第一次访问aspx页面时通过HTTP GET方法,而第二次以后都会通过HTTP POST方法,而HTTP POST方式进行访问服务器时,所需要经历的过程要比GET方式多,因为它包含了数据回传处理,下面是示意图:

       

     

       下面通过一个小Demo来查看控件的生命周期:

    Demo Post回传生命周期

     

     首先先写一个控件,对每个控件的上述事件进行覆盖,最后通过在页面Trace来查看

     

       首先是控件的代码:

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Web;

    using System.Web.UI;

     

    namespace Life

    {

        [ToolboxData("<{0}:lifecycle runat=server></{0}:lifecycle>")]

        public class Lifecycle : Control, IPostBackEventHandler, IPostBackDataHandler

        {

            protected override void OnInit(System.EventArgs e)

            {

                Trace("Lifecycle: Init Event.");

                base.OnInit(e);

            }

            protected override void TrackViewState()

            {

                Trace("Lifecycle: Track ViewState.");

                base.TrackViewState();

            }

            protected override void LoadViewState(object savedState)

            {

                Trace("Lifecycle: Load ViewState Event.");

                base.LoadViewState(savedState);

            }

            protected override void LoadControlState(object savedState)

            {

                Trace("Lifecycle: Load ControlState Event.");

                base.LoadControlState(savedState);

            }

            public override void DataBind()

            {

                Trace("Lifecycle: DataBind Event.");

                base.DataBind();

            }

            public bool LoadPostData(string postDataKey,NameValueCollection postCollection)

            {

                Trace("Lifecycle: Load PostBack Data Event.");

                Page.RegisterRequiresRaiseEvent(this);

                return true;

            }

            protected override void OnLoad(System.EventArgs e)

            {

                Trace("Lifecycle: Load Event.");

                base.OnLoad(e);

            }

            public void RaisePostDataChangedEvent()

            {

                Trace("Lifecycle: Post Data Changed Event.");

            }

            public void RaisePostBackEvent(string argument)

            {

                Trace("Lifecycle: PostBack Event.");

            }

            protected override void OnPreRender(System.EventArgs e)

            {

                Trace("Lifecycle: PreRender Event.");

                Page.RegisterRequiresPostBack(this);

                base.OnPreRender(e);

            }

            protected override object SaveViewState()

            {

                Trace("Lifecycle: Save ViewState.");

                return base.SaveViewState();

            }

            protected override object SaveControlState()

            {

                Trace("Lifecycle: Save ControlState.");

                return base.SaveControlState();

            }

            protected override void Render(HtmlTextWriter writer)

            {

                base.Render(writer);

                Trace("Lifecycle: Render Event.");

                writer.Write("<h3>LifeCycle Control</h3>");

            }

            protected override void OnUnload(System.EventArgs e)

            {

                Trace("Lifecycle: Unload Event.");

                base.OnUnload(e);

            }

            public override void Dispose()

            {

                Trace("Lifecycle: Dispose Event.");

                base.Dispose();

            }

            private void Trace(string info)

            {

                if (Context != null)

                {

                    Context.Trace.Warn(info);

                   System.Diagnostics.Debug.WriteLine(info);

                }

            }

        }

    }

    首先通过设置私有的Trace方法将Trace信息添加进页面当中,通过实现了IPostBackEventHandler和IPostBackDataHandler接口来实现Post方式回传所需要的几个方法。

     控件在前台的代码如下:

     首先在前台将Trace属性设置成True,其次注册控件

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default10.aspx.cs" Inherits="Default10" Trace="true" %>

    <%@ Register Namespace="Life" TagPrefix="lc" %>

     

    然后将控件放在页面内:

    <lc:Lifecycle runat="server"></lc:Lifecycle>

    输出结果如下:

      


       可以看出,我们对事件的实现都已经插入页面的生命周期内.

  • 相关阅读:
    element-ui 表格实现单元格可编辑的示例
    vue.js数组追加合并与对象追加合并
    Gym 101471G BZOJ 4954 [WF2017]Replicate Replicate Rfplicbte
    Gym 100299E BZOJ 4054 [CERC2013]Escape (启发式合并)
    Gym 101239E BZOJ 4110 [CERC2013]Evolution in Parallel (DP、结论)
    Gym 101221I BZOJ 4080 [WF2014]Sensor Network (二分图匹配)
    Gym 101190D BZOJ 4842 Luogu P6967 LOJ #6071 [NEERC2016]Delight for a Cat (费用流)
    记录一次dubbo不能正常抛出特定异常
    JAVA 类加载机制学习笔记
    JAVA 垃圾回收读书笔记
  • 原文地址:https://www.cnblogs.com/CareySon/p/1584106.html
Copyright © 2020-2023  润新知