用户操作
[即时聊天] [发私信] [加为好友]
生命的插曲ID:yonghengdizhen
532次访问,排名2万外好友23人,关注者41
数据库,数据仓库开发,管理
web开发
yonghengdizhen的文章
原创 2 篇
翻译 0 篇
转载 0 篇
评论 24 篇
最近评论
文章分类
收藏
相册
ORACLE
SQL SERVER
存档
软件项目交易
订阅我的博客
XML聚合  FeedSky
订阅到鲜果
订阅到Google
订阅到抓虾
订阅到BlogLines
订阅到Yahoo
订阅到GouGou
订阅到飞鸽
订阅到Rojo
订阅到newsgator
订阅到netvibes

原创 ASP.NET ViewState 实现分析收藏

 | 旧一篇: 我的Blog开通了

 

ProcessRequest开始

private void ProcessRequest();

Declaring Type:

System.Web.UI.Page

Assembly:

System.Web, Version=1.0.5000.0

private void ProcessRequest()

{

    Thread currentThread = Thread.CurrentThread;

    CultureInfo currentCulture = currentThread.CurrentCulture;

    CultureInfo currentUICulture = currentThread.CurrentUICulture;

    this.FrameworkInitialize();   //完成框架初始化,并构造静态控件树,位于由解析器生成,动态编译的用户代码中, 

    try

    {

        try

        {

            if (this.IsTransacted)

            {

                this.ProcessRequestTransacted();

            }

            else

            {

                this.ProcessRequestMain();  //页面事件流

            }

            this.ProcessRequestEndTrace();

        }

        finally

        {

            this.ProcessRequestCleanup();

            InternalSecurityPermissions.ControlThread.Assert();

            currentThread.CurrentCulture = currentCulture;

            currentThread.CurrentUICulture = currentUICulture;

        }

    }

    catch

    {

        throw;

    }

}

接下来从ProcessRequestMain开始

private void ProcessRequestMain();

Declaring Type:

System.Web.UI.Page

Assembly:

System.Web, Version=1.0.5000.0

private void ProcessRequestMain()

{

    try

    {

        if (this.IsInAspCompatMode)

        {

            AspCompatApplicationStep.OnPageStartSessionObjects();

        }

        this._requestValueCollection = this.DeterminePostBackMode();

        HttpContext context = this.Context;

        if (context.TraceIsEnabled)

        {

            this.Trace.Write("aspx.page", "Begin Init");

        }

        base.InitRecursive(null);

        if (context.TraceIsEnabled)

        {

            this.Trace.Write("aspx.page", "End Init");

        }

        if (this.IsPostBack)

        {

            if (context.TraceIsEnabled)

            {

                this.Trace.Write("aspx.page", "Begin LoadViewState");

            }

            this.LoadPageViewState();    //加载ViewState

            if (context.TraceIsEnabled)

            {

                this.Trace.Write("aspx.page", "End LoadViewState");

                this.Trace.Write("aspx.page", "Begin ProcessPostData");

            }

            this.ProcessPostData(this._requestValueCollection, true);  //首次加载回传数据(回传数据代表控件的当前值,ViewState代表控件的原来的值,由此两者的差异而导致随后触发控件的Change事件),加载完当前已加载控件的控件值之后,会为值发生过改变的控件调用Change事件注册过程,为导致回传的控件注册回传事件.

            if (context.TraceIsEnabled)

            {

                this.Trace.Write("aspx.page", "End ProcessPostData");

            }

        }

        base.LoadRecursive();

        if (this.IsPostBack)

        {

            if (context.TraceIsEnabled)

            {

                this.Trace.Write("aspx.page", "Begin ProcessPostData Second Try");

            }

            this.ProcessPostData(this._leftoverPostData, false);  //再此加载剩余的回传数据,并同样注册Change事件和PostBack事件

            if (context.TraceIsEnabled)

            {

                this.Trace.Write("aspx.page", "End ProcessPostData Second Try");

                this.Trace.Write("aspx.page", "Begin Raise ChangedEvents");

            }

            this.RaiseChangedEvents();  //用在回传事件处理过程中注册的发生过改变的控件来触发它们相应的事件处理过程

            if (context.TraceIsEnabled)

            {

                this.Trace.Write("aspx.page", "End Raise ChangedEvents");

                this.Trace.Write("aspx.page", "Begin Raise PostBackEvent");

            }

            this.RaisePostBackEvent(this._requestValueCollection);  //产生回传事件

            if (context.TraceIsEnabled)

            {

                this.Trace.Write("aspx.page", "End Raise PostBackEvent");

            }

        }

        if (context.TraceIsEnabled)

        {

            this.Trace.Write("aspx.page", "Begin PreRender");

        }

        base.PreRenderRecursiveInternal();  

//由于此处两次加载PostBack数据且触发change的时机均已错过,但尚未完成SaveViewState,所以,此处还有机会添加动态控件到控件树,并完成触发其包括Change事件在内的所有控件事件(Change事件需要手工触发)

触发代码如下所示

Control t = new TextBox();

((TextBox)t).ForeColor=Color.Red;

this.Controls[2].Controls.Add(t);

((TextBox)t).TextChanged += new System.EventHandler(this.TextBox1_TextChanged);

if(this.IsPostBack)

{

      NameValueCollection _requestValueCollection=this.DeterminePostBackMode();

      if(((IPostBackDataHandler)t).LoadPostData(t.UniqueID, _requestValueCollection))

      {

           ((IPostBackDataHandler)t).RaisePostDataChangedEvent();

      }           

}

        if (context.TraceIsEnabled)

        {

            this.Trace.Write("aspx.page", "End PreRender");

            base.BuildProfileTree("ROOT", this.EnableViewState);

            this.Trace.Write("aspx.page", "Begin SaveViewState");

        }

        this.SavePageViewState();  

//保存Page及全部控件的ViewState,此过程之后虽然可以通过重载Page.Render来实现动态加载控件,但由于已经错过了SaveViewState的机会,控件的状态得不到保存,因此,依赖ViewStatePostback数据进行比较而产生的change事件无法依据正确的逻辑触发,而且控件的当前值也需要LoadPostData手工加载

        if (context.TraceIsEnabled)

        {

            this.Trace.Write("aspx.page", "End SaveViewState");

            this.Trace.Write("aspx.page", "Begin Render");

        }

        base.RenderControl(this.CreateHtmlTextWriter(this.Response.Output));

        if (context.TraceIsEnabled)

        {

            this.Trace.Write("aspx.page", "End Render");

        }

    }

    catch (ThreadAbortException)

    {

        base.UnloadRecursive(true);

    }

    catch (ConfigurationException)

    {

        throw;

    }

    catch (Exception exception)

    {