背景知识
Page类的派生关系

Page是从TemplateControl中派生的,TemplateControlControl派生。他们的定义分别如下:

 

//Control,从object派生,实现了四个接口

public class Control : System.ComponentModel.IComponent,

     System.IDisposable,

     System.Web.UI.IParserAccessor,

     System.Web.UI.IDataBindingsAccessor

{

}

 

//TemplateControl从Control派生,实现了接口System.Web.UI.INamingContainer

public abstract class TemplateControl : Control, System.Web.UI.INamingContainer

{

}

 

//Page从TemplateControl派生,实现了接口System.Web.UI. IHttpHandler

public class Page : TemplateControl, System.Web.IHttpHandler

{

}

 

而你编写的Page,你在_aspx.cs文件中编写的类是从Page派生,这个继承关系是你添加WebForm页面时,Visual Studio .net帮你建好的。而aspx的页面在运行时会被解释为一个从_aspx.cs文件中的类的派生类。(这里需要补充资料)。

    

 

 

猜想

IIS接收到aspx页面一个请求,交给aspnet_isapi.dll处理。aspnet_isapi然后做以下的事情:

 

MyPage __p;

__p = new MyPage();

__p.ProcessRequest(System.Web.HttpContext.Current)

 

以上是我个人的估计,究竟事实是不是这样,我会找Microsoft的工程师要答案!我在System.Web.dll中没有找到处理产生Page实例的ilPage类的实例的创建可能是aspnet_isapi.dll作了,而aspnet_isapi.dll不是使用.net编写的,其内部的运行究竟如何无从得知。

 

以下不是猜想!

ProcessRequest(HttpContext)方法

Page中的ProcessRequest(System.Web.HttpContext)方法是这样的:

 

public virtual void ProcessRequest(Sunrise.Web.HttpContext context)

{

  this.SetIntrinsics(context); //进行最基本初始化

  this.ProcessRequest(); //处理请求

}

 

SetIntrinsics方法

从上面的代码可以看到,首先会调用SetIntrinsics(HttpContext context)方法,SetIntrinsics的作用是对Page的成员变量进行基本的初始化。SetIntrinsics如下:

 

//进行最基本初始化,设置_context、_request、_application、_cache的初值

private void  SetIntrinsics(HttpContext context)

{

     this._context = context;

     this._request =    context.Request;

     this._response = context.Response;

     this._application = context.Application;

     this._cache = context.Cache;

 

     if(this._clientTarget != null)

     {

         if(this._clientTarget.Length >0)

         {

              this._request.ClientTarget = this._clientTarget;

         }

     }

 

     //调TempalateControl的HookUpAutomaticHandlers()方法初始化基本事件

     //包括:Init、Load、DataBinding、PreRender、Unload、Error、

     //AbortTransaction、CommitTransaction

     this.HookUpAutomaticHandlers();

}

 

ProcessRequest方法

然后就开始执行ProcessRequest()方法,大致如下:

 

try

{

     if(this.IsTransacted) //如果是事务状态

     {

         this.ProcessRequestTransacted();

     }

     else //非事务状态

     {

         this.ProcessRequestMain();

     }

     this.ProcessRequestEndTrace();

}

finally

{

     //释放资源,把_request、_response置为null,并执行UnloadRecursive(true)

     this.ProcessRequestCleanup();

}

 

ProcessRequestMain方法

通过上面的代码可以知道,当一个Page是非事务模式是,响应ProcessRequestMain()。事实上,是事务模式时,也是调用ProcessRequestMain()。以下是关于ProcessRequestMain()方法的伪码:

//step1 调用Control.InitRecursive()进行递归初始化 Control的OnInit()方法将会在此时被调用

this.InitRecursive(null);

 

//如果是回传状态

if(this.IsPostBack)

{

     //step2 装载ViewState

     ///装载Page的ViewState,Control的LoadViewState()方法将会在这里被调用

     this.LoadPageViewState();

 

     //step3 处理回传的数据,如果Control实现了System.Web.UI.IPostBackDataHandler,

     //LoadPostData()方法在此时被调用

     this.ProcessPostData(this._requestValueCollection, true);

}

 

//step4 调用Control.LoadRecursive()方法装载SubControls

//Control的Load()方法在此时被调用

this.LoadRecursive();

 

//如果是回传状态

if(this.IsPostBack)

{

     //step 5 再次处理未处理完的回传数据,

     //注意第二次调用时第二个参数是false,而第一次是true

     //第二次处理回传数据的作用可能是用来处理在OnLoad中创建的Control的数据,??

     this.ProcessPostData(this._leftoverPostData, false);

 

     //step6 响应数据更改事件,

     //如果Control实现了System.Web.UI.IPostBackDataHandler接口,

     //Control的RaisePostDataChangedEvent()方法在此时被调用

     this.RaiseChangedEvents();

 

     //step7 响应回传事件 __dopostback()

     //如果Control实现了System.Web.UI.IPostBackEventHandler接口,Control的RaisePostBackEvent()方法在此时执行

     this.RaisePostBackEvent(this._requestValueCollection);

 

     //step8 调用Control的PreRenderRecursiveInternal()方法,

     //Control的OnPreRender()方法在此时被调用

     this.PreRenderRecursiveInternal();

}

 

//step9 BuiltTree 构建ViewState,

//ViewState使用通过LosFormatter对ViewState进行编码,保存在Trace中

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

 

//step10 保存Page的ViewState

//Control的SaveViewState()方法

this.SavePageViewState();

 

//step11 输出

//Control的Render()方法在此时被调用

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


 

ProcessRequestMain方法图示

 

Init

Load ViewState

Load PostData

Load

Load PostData

 

RaiseChangeEvents

 

RaisePostBackEvents

 

BuildProfileTree

 

SaveViewState

Render

Dispose

Unload

此时产生HTML代码

OnInit()方法被调用

OnLoad()方法被调用

处理回传数据

再次处理回传数据

响应数据修改事件,如TextBoxTextChagned

响应回传事件,客户端的__dopostback


ProcessRequestTransacted方法

事实上,在事务状态下,也是调用ProcessRequestMain()的,我们来看一下ProcessRequestTransacted的代码:

 

bool V_0;

System.Web.Util.TransactedCallback V_1;

 

V_0 = false;

 

//创建事务回调的delegate

V_1 = new System.Web.Util.TransactedCallback(this.ProcessRequestMain);

 

//在事务环境下调用ProcessRequestMain()

System.Web.Util.Transactions.InvokeTransacted(

     V_1,

     (System.EnterpriseServices.TransactionOption)(this._transactionMode),

     ref V_0

     );

 

if(V_0)

{

     this.OnAbortTransaction(System.EventArgs.Empty); //终止事务

}

else

{

     this.OnCommitTransaction(System.EventArgs.Empty); //提交事务

}

 

InitRecursive方法

ProcessRequestMain 方法中,首先执行ControlInitRecursive方法。在InitRecursive中,OnInit方法被执行。具体如下:

 

internal void InitRecursive(System.Web.UI.Control namingContainer) //ok

{

     string V_0;

     int V_1;

     int V_2;

     System.Web.UI.Control V_3;

 

     if(this._controls != null)

     {

//flag[128]表示是否实现了System.Web.UI.INamingContainer接口

         if(this.flags[128])

         {

              namingContainer = this;

         }

 

         //设置_controls为只读,并返回原来的_readOnlyErrorMsg,保存在V_0

         V_0 = this._controls.SetCollectionReadOnly("Parent_collections_readonly");

 

         V_1 = this._controls.Count;

 

         for(V_2 = 0;V_2 < V_1; V_2++)

         {

              V_3 = this._controls[V_2];

              V_3._namingContainer = namingContainer;

              if(namingContainer != null)

              {

                   if((V_3._id == null)

                       &&

                       (!(V_3.flags[64]))

                       )

                   {

                       this.GenerateAutomaticID();

                   }

              }

 

              V_3._page = this._page;

              V_3.InitRecursive(namingContainer);

 

         }

 

         //回复_controls原来的状态

         this._controls.SetCollectionReadOnly(V_0);

 

         this._controlState = Sunrise.Web.UI.ControlState.Initialized;

 

         //OnInit方法在此时被调用

         this.OnInit(System.EventArgs.Empty);

         this.TrackViewState();

     }

}


LoadPageViewState方法

ProcessRequestMain 方法中,执行InitRecursive方法进行初始化后,如果PageIsPostBack属性值为True,则会接着执行LoadPageViewState方法

 

LoadPageViewState应该结合来SavePageViewState来看,这样更容易理解。具体如下:

 

internal void LoadPageViewState()

{

     System.Web.UI.Triplet V_0;

     string V_1;

 

     //获得使用LosFormater反序列化(Deserialize)得到的对象

     V_0 = (System.Web.UI.Triplet)this.LoadPageStateFromPersistenceMedium();

 

     if(V_0 != null)

     {

         V_1 = (string)V_0.First;

         int.Parse(V_1,System.Globalization.NumberFormatInfo.InvariantInfo);

         this.GetTypeHashCode();

 

         //判断V_1和Page调用GetTypeHashCode()方法获得的值是否相等,

//并把比较结果保存在_fPageLayoutChanged ??

         this._fPageLayoutChanged = (int.Parse(V_1,System.Globalization.NumberFormatInfo.InvariantInfo) != this.GetTypeHashCode());

 

         if(!(this._fPageLayoutChanged))

         {

              //调用Control.LoadViewStateRecursive()方法,

//递归装载ViewState,

//Control的LoadViewState()方法将会在这里被执行

              this.LoadViewStateRecursive(V_0.Second);

 

              this._controlsRequiringPostBack = (System.Collections.ArrayList)V_0.Third;

         }

     }

}


LoadViewStateRecursive方法

通过观察LoadPageViewState的代码可以得知,LoadPageViewState中执行LoadViewStateRecursive来进行ControlLoadViewState过程。

 

LoadViewStateRecursive的过程大致是这样,把参数savedState转换为Triplet对象,使用Triplet对象的First做参数来执行LoadView方法,然后使用Triplet对象的Second和Third对Controls进行LoadViewStateRecursive

 

这个方法应该参照SaveViewStateRecursive一起阅读,这样更方便理解。如下:

 

internal void LoadViewStateRecursive(object savedState)

{

     System.Web.UI.Triplet V_0;

     System.Collections.ArrayList V_1;

     System.Collections.ArrayList V_2;

     Sunrise.Web.UI.ControlCollection V_3;

     int V_4;

     int V_5;

     int V_6;

     int V_7;

 

     //如果参数为null或EnableViewState为False

     if((savedState == null)

         || (this.flags[4]) //flags[4]表示EnableViewState,true时,EnableViewState为false,false时EnableViewState为true

         )

     {

         return;

     }

 

     //转换为Triplet对象,Triplet有三个public的Fields:First、Second、Third,使用Triplet表示使代码更直观,而且更快

     V_0 = (System.Web.UI.Triplet)savedState;

 

     //如果control的Page不为null,而且this.Page.IsPostBack为True,执行LoadViewState方法

     if((this.Page != null)

         && (this.Page.IsPostBack)

         )

     {

         this.LoadViewState(V_0.First);

     }

 

     //对this.Controls中的Control进行LoadViewState

     if(V_0.Second != null)

     {

         V_1 = (System.Collections.ArrayList)V_0.Second; //kes

         V_2 = (System.Collections.ArrayList)V_0.Third; //values

         V_3 = this.Controls;

         V_4 = V_3.Count;

         V_5 = V_1.Count;

 

         for(V_6=0; V_6 < V_5; V_6 ++)

         {

              V_7 = (int)V_1[V_6];

              if(V_7 < V_4)

              {

                   V_3[V_7].LoadViewStateRecursive(V_2[V_6]);

              }

              else

              {

                   if(this._controlsViewState == null)

                   {

                       this._controlsViewState = new System.Collections.Hashtable();

                   }

                   this._controlsViewState[V_7] = V_2[V_6];

              }

         }

     }

 

     //将_controlState设置为ViewStateLoaded

     this._controlState = Sunrise.Web.UI.ControlState.ViewStateLoaded;

}

 


LoadViewState方法

       LoadViewState方法的是Protected,当你构建自己的Control时,可以重载它。此时你应该在你写的LoadViewState方法里执行base. LoadViewState(something)ControlLoadViewState代码如下:

 

protected virtual void  LoadViewState(object savedState)

{

     object V_0;

 

     if(savedState != null)

     {

         this.ViewState.LoadViewState(savedState);

         V_0 = this.ViewState["Visible"];

 

         if(V_0 != null)

         {

              // flags[16]表示Visible,false时,Visible为true,值为false时,Visible为true

              this.flags[16] = (!((bool)V_0));

              this.flags[32] = true; // flags[32]表示是否已经LoadView ??

         }

     }

}

 

 


ProcessPostData方法

ProcessRequestMain执行了LoadPageViewState方法后,接着就是ProcessPostData,这个方法是用来处理回传数据。这个方法被执行两遍,分别在LoadRecursive之前和之后个执行一遍。第一次执行时,参数fBeforeLoad值为True,第二次为False

//处理回传的数据

//当fBeforeLoad为true时,是第一次调用,fBeforeLoad为false时,为第二次调用

private void ProcessPostData(System.Collections.Specialized.NameValueCollection postData, bool fBeforeLoad) //ok

{

     string V_0;

     Sunrise.Web.UI.Control V_1;

     System.Web.UI.IPostBackDataHandler V_2;

     bool V_3;

     System.Collections.ArrayList V_4;

     string V_5;

     System.Web.UI.IPostBackDataHandler V_6;

     bool V_7;

     System.Collections.IEnumerator V_8;

     System.IDisposable V_9;

 

     if(this._changedPostDataConsumers == null)

     {

         this._changedPostDataConsumers = new System.Collections.ArrayList();

     }

 

     if(postData != null)

     {

         V_8 = postData.GetEnumerator();

 

         try

         {

              while(V_8.MoveNext())

              {

                   V_0 = (string)V_8.Current;

 

                   if(V_0 != null)

                   {

                       //判断回传数据是否在系统PostFields内,

                       //s_systemPostFields包括__EVENTTARGET、__EVENTARGUMENT、__VIEWSTATE

                       if(!s_systemPostFields.Contains(V_0))

                       {

                            V_1 = this.FindControl(V_0); //在Page中查找匹配的Control

 

                            if((V_1 == null) //如果找不到,将数据保存在_leftoverPostData中

                                 && (fBeforeLoad)

                                 )

                            {

                                 if(this._leftoverPostData == null)

                                 {

                                     this._leftoverPostData = new System.Collections.Specialized.NameValueCollection();

                                 }

 

                                 this._leftoverPostData.Add(V_0,null);

                            }

                            else //如果找到了……

                            {

                            //如果找到的结果实现了System.Web.UI.IPostBackDataHandler接口,

                                 //调用RegisterRequiresRaiseEvent方法

//赋值给_registeredControlThatRequireRaiseEvent

                                 if(!(V_1 is System.Web.UI.IPostBackDataHandler))

                                 {

                                     if(V_1 is System.Web.UI.IPostBackEventHandler)

                                     {

                                          this.RegisterRequiresRaiseEvent(

                                               (System.Web.UI.IPostBackEventHandler)V_1

                                               );

                                     }

                                 }

                                 else//如果找到的结果没有实现System.Web.UI.IPostBackDataHandler接口

                                 {

                                     V_2 = (System.Web.UI.IPostBackDataHandler)V_1;

                                     V_3 = V_2.LoadPostData(V_0,this._requestValueCollection); //V_2装载回传数据

                                     if(V_3) //如果V_2装载回传数据时发现数据已经被修改,将登记V_2在_changedPostDataConsumers中

                                     {

                                          this._changedPostDataConsumers.Add(V_2);

                                     }

 

                                     //在_controlsRequiringPostBack中移去V_0

                                     //_controlsRequiringPostBack的值在LoadPageViewState()方法中被赋值

                                     if(this._controlsRequiringPostBack != null)

                                     {

                                          this._controlsRequiringPostBack.Remove(V_0);

                                     }

                                 }

                            }

                       }

                   }

              }

         }

         finally

         {

              V_9 = V_8 as System.IDisposable;

              if(V_9 != null)

              {

                   V_9.Dispose();

              }

         }

     }

 

     V_4 = null;

 

     //处理_controlsRequiringPostBack中剩下的数据项

     if(this._controlsRequiringPostBack != null)

     {

         V_8 = this._controlsRequiringPostBack.GetEnumerator();

         try

         {

              while(V_8.MoveNext())

              {

                   V_5 = (string)V_8.Current;

                   V_6 = (System.Web.UI.IPostBackDataHandler)this.FindControl(V_5);

 

                   if(V_6 != null)

                   {

//V_7装载回传数据

                       V_7 = V_6.LoadPostData(V_5,this._requestValueCollection);

 

//如果V_6装载回传数据时发现数据已经被修改,

//将登记V_6在_changedPostDataConsumers中

                       if(V_7)                     {

                            this._changedPostDataConsumers.Add(V_6);

                       }

                   }

                   else

                   {

                       if(fBeforeLoad) //如果是第一次调用,保留

                       {

                            if(V_4 == null)

                            {

                                 V_4 = new System.Collections.ArrayList();

                            }

                            V_4.Add(V_5);

                       }

                   }

              }

         }

         finally

         {

              V_9 = V_8 as System.IDisposable;

              if(V_9 != null)

              {

                   V_9.Dispose();

              }

         }

     }

 

//如果是第一次调用,值为未处理的数据项,第二次调用值为null

     this._controlsRequiringPostBack = V_4;

}

 


LoadRecursive方法

LoadRecursive方法的过程大致是这样,先执行Load方法,然后对Controls执行LoadRecursive。

 

代码如下:

 

internal void LoadRecursive()

{

     string V_0;

     int V_1;

     int V_2;

 

     //在这里执行OnLoad方法

     this.OnLoad(System.EventArgs.Empty);

 

     if(this._controls != null)

     {

         //设置_controls为只读

         V_0 = this._controls.SetCollectionReadOnly("Parent_collections_readonly");

 

         V_1 = this._controls.Count;

 

         for(V_2 = 0;V_2 < V_1; V_2++)

         {

              this._controls[V_2].LoadRecursive();

         }

 

         //回复原来的状态

         this._controls.SetCollectionReadOnly(V_0);

     }

 

     this._controlState = Sunrise.Web.UI.ControlState.Loaded;

}

 


RaiseChangedEvents方法

如果Control实现了System.Web.UI.IPostBackDataHandler接口,ControlRaisePostDataChangedEvent将会在这里被调用。需要的响应的RaisePostDataChangedEvent的典型例子是TextBoxTextBoxText数据在客户端可能被修改,如果修改了,需要获得通知,以响应TextChanged事件。

 

internal void RaiseChangedEvents() //ok

{

     int V_0;

     System.Web.UI.IPostBackDataHandler V_1;

     Sunrise.Web.UI.Control V_2;

 

     if(this._changedPostDataConsumers != null)

     {

         for(V_0=0; V_0 < this._changedPostDataConsumers.Count; V_0++)

          {

              V_1 = (System.Web.UI.IPostBackDataHandler)this._changedPostDataConsumers[V_0];

              V_2 = V_1 as Sunrise.Web.UI.Control;

 

              //如果V_2是Page的SubControls,调用RaisePostDataChangedEvent()

              if((V_2 != null)

                   ||

                   (V_2.IsDescendentOf(this))

                   )

              {

                   V_1.RaisePostDataChangedEvent();

              }

         }

     }

}

 


RaisePostBackEvent方法

 

当执行ClientJavaScript__dopostback()函数时,将产生回传事件。(此处需要补充资料)。回传事件的原理是,Page产生的HTML代码中,会产生两个隐藏域(Hidden),__EVENTTARGET和__ EVENTARGUMENT,不同的Control产生执行__dopostback()的方法不一致。调用的时候大多数是这样:

 

<input type=hidden name=__EVENTTARGET>

<input type=hidden name=__ EVENTARGUMENT>

 

__dopostback(control_uniqueid, ‘’);

 

Form提交的时候,RaisePostBackEvent根据control_uniqueid来找到需要响应事件的Server Control。__ EVENTARGUMENT是事件的参数,参数在开发简单的Server Control通常是不需要,在复杂的Server Control时才用。

例如System.Web.UI.WebControls.LinkButton

 

private void RaisePostBackEvent(System.Collections.Specialized.NameValueCollection postData)

{

     string V_0;

     Sunrise.Web.UI.Control V_1;

     string V_2;

 

     if(this._registeredControlThatRequireRaiseEvent != null)

     {

         this.RaisePostBackEvent(_registeredControlThatRequireRaiseEvent, null);

         return;

     }

 

     V_0 = postData["__EVENTTARGET"];

 

     if((V_0 != null)

         &&

         (V_0.Length >0)

         )

     {

         V_1 = this.FindControl(V_0);

 

         if((V_1 != null)

              && (V_1 is System.Web.UI.IPostBackEventHandler)

              )

         {

              V_2 = postData["__EVENTARGUMENT"];

              this.RaisePostBackEvent((System.Web.UI.IPostBackEventHandler)V_1, V_2);

         }

     }

     else

     {

         this.Validate();

     }

}

 


PreRenderRecursiveInternal方法

       ControlPrenRender方法会在这里被执行。代码如下:

 

internal void PreRenderRecursiveInternal()

{

     string V_0;

     int V_1;

     int V_2;

 

     // flags[16]表示Visible,false时,Visible为true,值为false时,Visible为true

     if(!(this.flags[16]))

     {

         this.EnsureChildControls();

 

         //OnPreRender在这里被执行

         this.OnPreRender(System.EventArgs.Empty);

 

         if(this._controls != null)

         {

              //设置只读

              V_0 = this._controls.SetCollectionReadOnly("Parent_collections_readonly");

 

              V_1 = this._controls.Count;

 

              for(V_2 = 0;V_2 < V_1; V_2++)

              {

                   this._controls[V_2].PreRenderRecursiveInternal();

              }

 

              //回复原来的状态

              this._controls.SetCollectionReadOnly(V_0);

         }

     }

 

     this._controlState = Sunrise.Web.UI.ControlState.PreRendered;

}


BuildProfileTree 方法

构建ViewState的存放空间,放在Trace里。(此处需要更详细的说明)

protected void BuildProfileTree(string parentId, bool calcViewState)

{

     int V_0;

     int V_1;

     int V_2;

 

     calcViewState = calcViewState || (!(this.flags[4]));

 

     if(calcViewState)

     {

         //计算LosFormatter会产生编码结果的长度

         V_0 = Sunrise.Web.UI.LosFormatter.EstimateSize(this.SaveViewState());

     }

     else

     {

         V_0 = 0;

     }

 

     this.Page.Trace.AddNewControl(

         this.UniqueID,

         parentId,

         this.GetType().FullName,

         V_0

         );

 

     if(this._controls != null)

     {

         V_1 = this._controls.Count;

         for(V_2 =0; V_2 < V_1; V_2 ++)

         {

              this._controls[V_2].BuildProfileTree(this.UniqueID, calcViewState);

         }

     }

}


SavePageViewState 方法

保存PageViewStateLosFormatter的编码结果放置于_viewStateToPersist中。此方法应该结合LoadPageViewState一起来分析。

使用TripletPair保存ViewState时常用的技巧。这里使用了Triplet

(需要补充关于LosFormatter的说明)

 

SavePageViewStateSavePageStateToPersistenceMedium的代码如下:

 

internal void SavePageViewState()

{

     System.Web.UI.Triplet V_0;

     int V_1;

 

     if(!(this._needToPersistViewState))

     {

         return;

     }

 

     V_0 = new System.Web.UI.Triplet();

     V_1 = this.GetTypeHashCode();

 

     //将数字转换为字符

     V_0.First = V_1.ToString(System.Globalization.NumberFormatInfo.InvariantInfo);

 

     //_registeredControlsThatRequirePostBack是一个ArrayList,

     //其内容项 RegisterRequiresPostBack(System.Web.UI.Control control)来添加

     V_0.Third = this._registeredControlsThatRequirePostBack;

 

     if(this.Context.TraceIsEnabled)

     {

         this.Trace.AddControlViewstateSize(

              this.UniqueID,

              Sunrise.Web.UI.LosFormatter.EstimateSize(V_0)

              );

     }

 

//执行SaveViewStateRecursive()方法,把返回结果保存赋给V_0.Second。

     V_0.Second = this.SaveViewStateRecursive();

 

     this.SavePageStateToPersistenceMedium(V_0);

}

 

protected virtual void SavePageStateToPersistenceMedium(object viewState)

{

     this._viewStateToPersist = viewState;

}

 


SaveViewStateRecursive方法

SavePageViewState方法中执行SaveViewStateRecursive方法来获取ControlTreeSaveViewState的结果。

 

internal object SaveViewStateRecursive()

{

     object V_0;

     System.Collections.ArrayList V_1;

     System.Collections.ArrayList V_2;

     int V_3;

     int V_4;

     Sunrise.Web.UI.Control V_5;

     object V_6;

     System.Web.UI.Triplet V_7;

 

     if(this.flags[4])

     {

         return(null);

     }

 

     //获得Control本身的SaveViewState()结果

     V_0 = this.SaveViewState();

     V_1 = null;

     V_2 = null;

    

     //获取SubControls的SaveViewStateRecursive()结果

     if(this._controls != null)

     {

         V_3 = this._controls.Count;

        

         for(V_4=0; V_4<V_3; V_4++)

         {

              V_5 = this._controls[V_4];

              V_6 = V_5.SaveViewStateRecursive();

 

              if(V_6 != null)

              {

                   if(V_1 == null)

                   {

                       V_1 = new System.Collections.ArrayList();

                       V_2 = new System.Collections.ArrayList();

                       V_1.Add(V_4);

                       V_2.Add(V_6);

                   }

              }

         }

     }

 

     V_7 = null;

 

     //如果Control本身的SaveViewState()结果不为null,

     //而且SuControls的SaveViewStateRecursive()结果不为null

     if((V_0 != null)

         || (V_1 != null)

         )

     {

         V_7 = new System.Web.UI.Triplet(V_0, V_1, V_2);

     }

 

     return(V_7);

}

 


RenderControl方法

ProcessRequestMain()执行了PreRenderRecursive后,接着就执行RenderControl方法。RenderControl是在Control中定义的方法。RenderControl是执行ControlRender方法,输出html文本。

public void  RenderControl(System.Web.UI.HtmlTextWriter writer) //ok

{

     System.Web.HttpContext V_0;

     int V_1;

     int V_2;

 

     // flags[16]表示Visible,false时,Visible为true,值为false时,Visible为true

     if(!(this.flags[16]))

     {

         //如果this._page不为null,……

         V_0 = (this._page == null) ? null: this._page._context;

 

         if(V_0 != null)

         {

              if(V_0.TraceIsEnabled)

              {

                   V_1 =V_0.Response.GetBufferedLength();

 

                   //Render方法在这里被执行

                   this.Render(writer);

 

                   V_2 = V_0.Response.GetBufferedLength();

                   V_0.Trace.AddControlSize(this.UniqueID, V_2 - V_1);

              }

         }

         else

         {

              //Render方法在这里被执行

              this.Render(writer);

         }

     }

}


RenderRenderChildren

RenderRenderChildren都可以被重载。在System.Web.UI.WebControls命名空间里,大部分Control都是从System.Web.UI.WebControls.WebControl中派生的,WebControl重载Render方法,分拆成三个方法,RenderBeginTageRenderContentRenderEndTag。如果Cotnrol是从WebControl中派生,通常只需要重载RenderContent

 

下面是Control中的代码:

 

protected virtual void Render(System.Web.UI.HtmlTextWriter writer)

{

     this.RenderChildren(writer);

}

 

protected virtual void RenderChildren(System.Web.UI.HtmlTextWriter writer) //ok

{

     int V_0;

     int V_1;

     if(this._renderMethod != null)

     {

         this._renderMethod(writer,this);

     }

     else

     {

         if(this._controls != null)

          {

              V_0 = this._controls.Count;

              for(V_1=0; V_1<V_0; V_1 ++)

              {

                   this._controls[V_1].RenderControl(writer);

              }

        

posted on 2006-09-30 11:59  老夫狂傲江湖  阅读(680)  评论(0编辑  收藏  举报