ASP.NET ViewState 实现分析(转)

从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的机会,控件的状态得不到保存,因此,依赖ViewState和Postback数据进行比较而产生的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)
    {
        PerfCounters.IncrementCounter(AppPerfCounter.ERRORS_DURING_REQUEST);
        PerfCounters.IncrementCounter(AppPerfCounter.ERRORS_TOTAL);
        
if (!this.HandleError(exception))
        {
            
throw;
        }
    }
}
internal void LoadPageViewState();
 
Declaring Type: 
 System.Web.UI.Page 
 
Assembly: 
 System.Web, Version
=1.0.5000.0 
 

internal void LoadPageViewState()
{
Triplet triplet 
= (Triplet) this.LoadPageStateFromPersistenceMedium();  
//获取从表单域__ViewState中反序列化之后的ViewState
    if (triplet != null)
    {
        
string s = (string) triplet.First;
        
int.Parse(s, NumberFormatInfo.InvariantInfo);
        
this._fPageLayoutChanged = int.Parse(s, NumberFormatInfo.InvariantInfo) != this.GetTypeHashCode();
//由解析器生成的动态用户代码实现,每次重新编译后,返回值唯一,用于检测Page(aspx)是否修改过半
        if (!this._fPageLayoutChanged)
        {
            
base.LoadViewStateRecursive(triplet.Second);    //递归加载控件树的ViewState
this._controlsRequiringPostBack = (ArrayList) triplet.Third;
//还原ViewState中保存过的需要PostBack的控件,这些控件通过Page.RegisterRequiresPostBack方法将自身注册到Page._registeredControlsThatRequirePostBack,并在Page.SavePageViewState时传递给Page的状态包,最终在base.RenderControl时由HtmlForm.Render方法将其转换成名为__ViewState的表单域,用于回传时的反序列化
        }
    }
}
protected virtual object LoadPageStateFromPersistenceMedium();
 
Declaring Type: 
 System.Web.UI.Page 
 
Assembly: 
 System.Web, Version
=1.0.5000.0 
 

  

protected virtual object LoadPageStateFromPersistenceMedium()
{
    
object obj2;
    
if (this._requestValueCollection == null)
    {
        
return null;
    }
    
string input = this._requestValueCollection["__VIEWSTATE"];
    
if (input == null)
    {
        
return null;
    }
    
if (this._formatter == null)
    {
        
this.CreateLosFormatter();
    }
    
try
    {
        obj2 
= this._formatter.Deserialize(input);
    }
    
catch (Exception exception)
    {
        
string text2 = this._response.IsClientConnected ? "Invalid_Viewstate" : "Invalid_Viewstate_Client_Disconnected";
        
throw new HttpException(text2 + SR.GetString("Invalid_Viewstate_Response_Data"new object[] { this._request.ServerVariables["REMOTE_ADDR"], this._request.ServerVariables["REMOTE_PORT"], this._request.ServerVariables["HTTP_USER_AGENT"], input, this._request.ServerVariables["HTTP_REFERER"], this._request.ServerVariables["PATH_INFO"] }), exception);
    }
    
return obj2;
}
internal void LoadViewStateRecursive(object savedState);
 
Declaring Type: 
 System.Web.UI.Control 
 
Assembly: 
 System.Web, Version
=1.0.5000.0 
 

internal void LoadViewStateRecursive(object savedState)
{
    
if ((savedState != null&& !this.flags[4])     //flags[4]=Disable ViewState
    {
        Triplet triplet 
= (Triplet) savedState;
        
if ((this.Page != null&& this.Page.IsPostBack)
        {
            
try
            {
                
this.LoadViewState(triplet.First); //加载当前控件的ViewState状态,由各控件派生类实现,将状态包关联到自身
            }
            
catch (InvalidCastException)
            {
                
throw new HttpException(HttpRuntime.FormatResourceString("Controls_Cant_Change_Between_Posts"));
            }
            
catch (IndexOutOfRangeException)
            {
                
throw new HttpException(HttpRuntime.FormatResourceString("Controls_Cant_Change_Between_Posts"));
            }
        }
        
if (triplet.Second != null)
        {
            ArrayList second 
= (ArrayList) triplet.Second; //此处保存所有保存过ViewState的控件在原包含器(即当前控件)中的位置索引
            ArrayList third = (ArrayList) triplet.Third;      //此处保存每一个当前控件的子控件(截止当前调用时为止已经被加载过的控件,包括由Page.FrameworkInitialize加载的静态控件以及在base.InitRecursive(null)时动态创建的控件)
            ControlCollection controls = this.Controls;
            
int count = controls.Count;
            
int num2 = second.Count;
            
for (int i = 0; i < num2; i++)
            {
                
int num4 = (int) second[i];
                
if (num4 < count)   //若ViewState中控件的索引超过当前已加载控件数,则表明这至少是在LoadPageViewState之后才创建的控件(动态控件),这类的控件的ViewState先保存在容器的_controlsViewState中,待稍后控件被添加到该容器时再和该控件关联(Controls.Add),否则,调用控件的加载ViewState的方法,重复以本过程,直至所有的控件的ViewState均已加载完毕
                {
                    controls[num4].LoadViewStateRecursive(third[i]);
                }
                
else
                {
                    
if (this._controlsViewState == null)
                    {
                        
this._controlsViewState = new Hashtable();
                    }
                    
this._controlsViewState[num4] = third[i];
                }
            }
        }
        
this._controlState = ControlState.ViewStateLoaded;
    }
}
protected internal virtual void AddedControl(Control control, int index);
 
Declaring Type: 
 System.Web.UI.Control 
 
Assembly: 
 System.Web, Version
=1.0.5000.0 
 

protected internal virtual void AddedControl(Control control, int index)
{
    
if (control._parent != null)
    {
        control._parent.Controls.Remove(control);
    }
    control._parent 
= this;
    control._page 
= this._page;
    Control namingContainer 
= this.flags[0x80? this : this._namingContainer;  //flags[0x80]= naming Container
    if (namingContainer != null)
    {
        control._namingContainer 
= namingContainer;
        
if ((control._id == null&& !control.flags[0x40])
        {
            control.GenerateAutomaticID();
        }
        
else if ((control._id != null|| (control._controls != null))
        {
            namingContainer.DirtyNameTable();
        }
}
//由以下过程可以看出,实际上动态加载的控件其自Init至Render前的所有 (在Page生命周期中已经错过触发时机的) 事件均顺序触发,而非和Page生命周期事件交替进行
    if (this._controlState >= ControlState.ChildrenInitialized) //若容器已经初始化过,则显式调用动态加载控件的初始化过程
    {
        control.InitRecursive(namingContainer);
        
if (this._controlState >= ControlState.ViewStateLoaded)  //若容器已经加载过ViewState,则显式调用动态加载控件的加载ViewState过程
        {
            
object savedState = null;
            
if (this._controlsViewState != null)
            {
                savedState 
= this._controlsViewState[index];  //从容器保存的ViewState还原此控件的ViewState
                this._controlsViewState.Remove(index);
            }
            control.LoadViewStateRecursive(savedState);
            
if (this._controlState >= ControlState.Loaded)  //若容器已经加载过,则显式调用动态加载控件的加载过程
            {
                control.LoadRecursive();
                
if (this._controlState >= ControlState.PreRendered)  //若容器已经PreRender过,则显式调用动态加载控件的PreRender过程
                {
                    control.PreRenderRecursiveInternal();
                }
            }
        }
    }
}
private void ProcessPostData(NameValueCollection postData, bool fBeforeLoad);
 
Declaring Type: 
 System.Web.UI.Page 
 
Assembly: 
 System.Web, Version
=1.0.5000.0 
 

private void ProcessPostData(NameValueCollection postData, bool fBeforeLoad)
{
    
if (this._changedPostDataConsumers == null)
    {
        
this._changedPostDataConsumers = new ArrayList();
    }
    
if (postData != null)
    {
        
foreach (string text in postData)
        {
            
if ((text == null|| s_systemPostFields.Contains(text))  //忽略系统使用的表单域
            {
                
continue;
            }
            Control control 
= this.FindControl(text);
            
if (control == null)   //忽略当前尚未加载进控件树的控件,若这是首次加载回传数据,将该数据保存到Page. _leftoverPostData留待第二次加载回传数据时再处理    
            {
                
if (fBeforeLoad)
                {
                    
if (this._leftoverPostData == null)
                    {
                        
this._leftoverPostData = new NameValueCollection();
                    }
                    
this._leftoverPostData.Add(text, null);
                }
                
continue;
            }
            
if (!(control is IPostBackDataHandler))
            {
                
if (control is IPostBackEventHandler)
                {
this.RegisterRequiresRaiseEvent((IPostBackEventHandler) control);
//如果回传数据中有仅仅实现了IPostBackEventHandler的控件存在,则说明此次PostBack是由一种仅实现Submit功能的HTML控件,或其WebControls封装引起,此处进行这类控件的事件注册.具备这个特性的控件在一次回传中仅存在一个
目前来说有
System.Web.UI.HtmlControls.HtmlAnchor
System.Web.UI.HtmlControls.HtmlButton
System.Web.UI.HtmlControls.HtmlInputButton
System.Web.UI.WebControls.Button
System.Web.UI.WebControls.Calendar
System.Web.UI.WebControls.LinkButton
按理来说System.Web.UI.HtmlControls.HtmlInputImage及System.Web.UI.WebControls.ImageButton也应该属于这类控件,但由于其Post时的特殊性实际上它还具备有IPostBackDataHandler的特性,所以不在此列
                }
                
continue;
            }
            IPostBackDataHandler handler 
= (IPostBackDataHandler) control;
if (handler.LoadPostData(text, this._requestValueCollection))  
//调用控件的方法加载回传数据,并和先前有ViewState加载过来的数据比较,以此来决定是否要为该控件触发Change事件,对于同时实现了IPostBackEventHandler,且对应的HTML控件内置了submit功能的控件(如System.Web.UI.HtmlControls.HtmlInputImage, System.Web.UI.WebControls.ImageButton),此方法还需调用this.RegisterRequiresRaiseEvent((IPostBackEventHandler) control),因为对于内置了submit功能的HTML控件及其WebControl封装在表单回传时不会调用客户端的脚本__doPostBack,当然也将不会通过回传表单的__EVENTTARGET域传递引发回传的对象
            {
                
this._changedPostDataConsumers.Add(handler);
            }
            
if (this._controlsRequiringPostBack != null)
            {
                
this._controlsRequiringPostBack.Remove(text);  //对于已经处理过回传的,随后的处理过程中将不再重复处理
            }
        }
    }
    ArrayList list 
= null;
    
if (this._controlsRequiringPostBack != null)
    {
        
foreach (string text2 in this._controlsRequiringPostBack)  //保证每一个通过Page.RegisterRequiresPostBack注册的控件都有机会加载回传数据和触发Change事件
        {
            Control control2 
= this.FindControl(text2);
            
if (control2 != null)
            {
                IPostBackDataHandler handler2 
= control2 as IPostBackDataHandler;
                
if (handler2 == null)
                {
                                        
//注册为需要PostBack的控件必须是实现为IPostBackDataHandler的控件,否则抛出异常
                    throw new HttpException(HttpRuntime.FormatResourceString("Postback_ctrl_not_found", text2));
                }
                
if (handler2.LoadPostData(text2, this._requestValueCollection))
                {
                    
this._changedPostDataConsumers.Add(handler2);
                }
                
continue;
}
//需要处理回传的控件,若在首次加载回传数据时没有机会处理到(通常是控件尚未加载到控件树中),将其保留下来,等待下次处理回传时再尝试,否则将被忽略
            if (fBeforeLoad)
            {
                
if (list == null)
                {
                    list 
= new ArrayList();
                }
                list.Add(text2);
            }
        }
        
this._controlsRequiringPostBack = list;
    }
}
bool IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection postCollection);
 
Declaring Type: 
 System.Web.UI.WebControls.ImageButton 
 
Assembly: 
 System.Web, Version
=1.0.5000.0 
 

bool IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection postCollection)
{
    
string uniqueID = this.UniqueID;
    
string s = postCollection[uniqueID + ".x"];
    
string text3 = postCollection[uniqueID + ".y"];
    
if (((s != null&& (text3 != null)) && ((s.Length > 0&& (text3.Length > 0)))
    {
        
this.x = int.Parse(s);
        
this.y = int.Parse(text3);
        
this.Page.RegisterRequiresRaiseEvent(this);
    }
    
return false;
}
bool IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection postCollection);
 
Declaring Type: 
 System.Web.UI.WebControls.TextBox 
 
Assembly: 
 System.Web, Version
=1.0.5000.0 
 

bool IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection postCollection)
{
    
string text = this.Text;
    
string text2 = postCollection[postDataKey];
    
if (!text.Equals(text2))
    {
        
this.Text = text2;
        
return true;
    }
    
return false;
}
  

public virtual void RegisterRequiresRaiseEvent(IPostBackEventHandler control);
 
Declaring Type: 
 System.Web.UI.Page 
 
Assembly: 
 System.Web, Version
=1.0.5000.0 
 

public virtual void RegisterRequiresRaiseEvent(IPostBackEventHandler control)
{
      
//由于每次导致回传的控件只可能存在一个,所以此处只保存一个引用
this._registeredControlThatRequireRaiseEvent = control;
}
internal void RaiseChangedEvents();
 
Declaring Type: 
 System.Web.UI.Page 
 
Assembly: 
 System.Web, Version
=1.0.5000.0 
 

 
internal void RaiseChangedEvents()
{
    
if (this._changedPostDataConsumers != null)
    {
        
for (int i = 0; i < this._changedPostDataConsumers.Count; i++)
        {
            IPostBackDataHandler handler 
= (IPostBackDataHandler) this._changedPostDataConsumers[i];
            Control control 
= handler as Control;
            
if ((control == null|| control.IsDescendentOf(this))
            {
                handler.RaisePostDataChangedEvent();   
//产生回传数据change事件
            }
        }
    }
}
void IPostBackDataHandler.RaisePostDataChangedEvent();
 
Declaring Type: 
 System.Web.UI.WebControls.ImageButton 
 
Assembly: 
 System.Web, Version
=1.0.5000.0 
 

void IPostBackDataHandler.RaisePostDataChangedEvent()
{
     
//由于对ImageButton来说,PostBack数据除了对于提取控件名称有用之外,完全没有意义,所以此过程实现为空
}
void IPostBackDataHandler.RaisePostDataChangedEvent();
 
Declaring Type: 
 System.Web.UI.WebControls.TextBox 
 
Assembly: 
 System.Web, Version
=1.0.5000.0 
 

void IPostBackDataHandler.RaisePostDataChangedEvent()
{
    
this.OnTextChanged(EventArgs.Empty);  //TextBox则用此方法来产生TextChange事件
}
protected virtual void OnTextChanged(EventArgs e);
 
Declaring Type: 
 System.Web.UI.WebControls.TextBox 
 
Assembly: 
 System.Web, Version
=1.0.5000.0 
 

protected virtual void OnTextChanged(EventArgs e)
{
    EventHandler handler 
= (EventHandler) base.Events[EventTextChanged];
    
if (handler != null)
    {
        handler(
this, e);    //调用由用户代码实现的TextChanged事件
    }
}
private void RaisePostBackEvent(NameValueCollection postData);
 
Declaring Type: 
 System.Web.UI.Page 
 
Assembly: 
 System.Web, Version
=1.0.5000.0 
 

private void RaisePostBackEvent(NameValueCollection postData)
{
    
if (this._registeredControlThatRequireRaiseEvent != null)
{
          
//若由仅实现回传功能(IPostBackEventHandler)的控件产生回传,那么调用该控件的回传事件,对于按钮类控件来说,通常触发Click事件和Command事件
        this.RaisePostBackEvent(this._registeredControlThatRequireRaiseEvent, null);
    }
    
else
{
        
string id = postData["__EVENTTARGET"];
        
if ((id != null&& (id.Length > 0))
        {
            Control control 
= this.FindControl(id);
            
if ((control != null&& (control is IPostBackEventHandler))
            {
                
string eventArgument = postData["__EVENTARGUMENT"];
                           
//对于实现IPostBackEventHandler的控件引起的回传,以回传时传回的引起回传的控件来调用回传事件
                this.RaisePostBackEvent((IPostBackEventHandler) control, eventArgument);
            }
        }
        
else
        {
            
this.Validate();
        }
    }
}
void IPostBackEventHandler.RaisePostBackEvent(string eventArgument);
 
Declaring Type: 
 System.Web.UI.WebControls.ImageButton 
 
Assembly: 
 System.Web, Version
=1.0.5000.0 
 

void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
{
    
if (this.CausesValidation)
    {
        
this.Page.Validate();
    }
    
this.OnClick(new ImageClickEventArgs(this.x, this.y));  //触发Click事件
    this.OnCommand(new CommandEventArgs(this.CommandName, this.CommandArgument));//触发可冒泡的事件
}
protected virtual void OnClick(ImageClickEventArgs e);
 
Declaring Type: 
 System.Web.UI.WebControls.ImageButton 
 
Assembly: 
 System.Web, Version
=1.0.5000.0 
 

protected virtual void OnClick(ImageClickEventArgs e)
{
    ImageClickEventHandler handler 
= (ImageClickEventHandler) base.Events[EventClick];
    
if (handler != null)
    {
        handler(
this, e); //调用注册过的控件Click事件
    }
}
protected virtual void OnCommand(CommandEventArgs e);
 
Declaring Type: 
 System.Web.UI.WebControls.ImageButton 
 
Assembly: 
 System.Web, Version
=1.0.5000.0 
 

protected virtual void OnCommand(CommandEventArgs e)
{
    CommandEventHandler handler 
= (CommandEventHandler) base.Events[EventCommand];
    
if (handler != null)
    {
        handler(
this, e); //调用注册过的控件Command事件
    }
    
base.RaiseBubbleEvent(this, e);   //冒泡,给容器以机会处理该事件
}
protected void RaiseBubbleEvent(object source, EventArgs args);
 
Declaring Type: 
 System.Web.UI.Control 
 
Assembly: 
 System.Web, Version
=1.0.5000.0 
 

protected void RaiseBubbleEvent(object source, EventArgs args)
{
    
for (Control parent = this._parent; parent != null; parent = parent.Parent)
    {
        
if (parent.OnBubbleEvent(source, args))  //沿控件树通向根的路径依次传递事件
目前实现该虚拟方法的仅为以下控件:
System.Web.UI.WebControls.DataGrid
System.Web.UI.WebControls.DataGridItem
System.Web.UI.WebControls.DataList
System.Web.UI.WebControls.DataListItem
System.Web.UI.WebControls.Repeater
System.Web.UI.WebControls.RepeaterItem
        {
            
return;
        }
    }
}
internal void SavePageViewState();
 
Declaring Type: 
 System.Web.UI.Page 
 
Assembly: 
 System.Web, Version
=1.0.5000.0 
 

 
internal void SavePageViewState()
{
    
if (this._needToPersistViewState)   //页面支持保存ViewState
    {
        Triplet triplet 
= new Triplet();
        triplet.First 
= this.GetTypeHashCode().ToString(NumberFormatInfo.InvariantInfo);  //保存解析器动态生成的hash值进ViewState,保证在aspx页面被动态修改后加载页面时旧的ViewState被抛弃.
        triplet.Third = this._registeredControlsThatRequirePostBack;  //由于此处传递为引用,所以即使在重载的Render方法中动态创建的需要回传的控件,也能被注册进该字段,直至整个页面开始序列化到表单的__ViewState中,而此序列化过程在base.RenderControl 在调用HtmlForm. RenderChildren时由HtmlForm. OnFormRender去完成
        if (this.Context.TraceIsEnabled)
        {
            
this.Trace.AddControlViewstateSize(this.UniqueID, LosFormatter.EstimateSize(triplet));
        }
        triplet.Second 
= base.SaveViewStateRecursive();   //保存页面子控件的ViewState
        this.SavePageStateToPersistenceMedium(triplet);
    }
}
internal object SaveViewStateRecursive();
 
Declaring Type: 
 System.Web.UI.Control 
 
Assembly: 
 System.Web, Version
=1.0.5000.0 
 

internal object SaveViewStateRecursive()
{
    
if (this.flags[4])   //控件禁用ViewState
    {
        
return null;
    }
    
object x = this.SaveViewState();    //保存当前控件的ViewState,
    ArrayList y = null;
    ArrayList z 
= null;
    
if (this._controls != null)
    {
        
int count = this._controls.Count;
        
for (int i = 0; i < count; i++)
        {
            
object obj3 = this._controls[i].SaveViewStateRecursive();  //打包子控件的ViewState
            if (obj3 != null)
            {
                
if (y == null)
                {
                    y 
= new ArrayList();   
                    z 
= new ArrayList();
                }
                y.Add(i);    
//为子控件的ViewState保存其在容器中的序号
 z.Add(obj3);   //保存打包好的子控件的ViewState到相应的位置
            }
        }
    }
    
if ((x == null&& (y == null))
    {
        
return null;
    }
    
return new Triplet(x, y, z);   //返回打包好的当前控件及其子控件的ViewState
}
protected virtual void SavePageStateToPersistenceMedium(object viewState);
 
Declaring Type: 
 System.Web.UI.Page 
 
Assembly: 
 System.Web, Version
=1.0.5000.0 
 

protected virtual void SavePageStateToPersistenceMedium(object viewState)
{
      
//保存打包好的整个页面的ViewState
    this._viewStateToPersist = viewState;
}
public void RenderControl(HtmlTextWriter writer);
 
Declaring Type: 
 System.Web.UI.Control 
 
Assembly: 
 System.Web, Version
=1.0.5000.0 
 

public void RenderControl(HtmlTextWriter writer)
{
    
if (!this.flags[0x10])   //控件非隐藏
    {
        HttpContext context 
= (this._page == null? null : this._page._context;
        
if ((context != null&& context.TraceIsEnabled)
        {
            
int bufferedLength = context.Response.GetBufferedLength();
            
this.Render(writer);
            
int num2 = context.Response.GetBufferedLength();
            context.Trace.AddControlSize(
this.UniqueID, num2 - bufferedLength);
        }
        
else
        {
            
this.Render(writer);  //渲染该控件及其子控件,Page的Render之后就是HtmlForm的Render
        }
    }
}
protected override void Render(HtmlTextWriter output);
 
Declaring Type: 
 System.Web.UI.HtmlControls.HtmlForm 
 
Assembly: 
 System.Web, Version
=1.0.5000.0 
 

protected override void Render(HtmlTextWriter output)
{
    Page page 
= this.Page;
    
if (page == null)
    {
        
throw new HttpException(HttpRuntime.FormatResourceString("Form_Needs_Page"));
    }
    
if (page.SmartNavigation)    //处理智能导航
    {
        
this.SetAttribute("__smartNavEnabled""true");
        output.WriteLine(
"<IFRAME ID=__hifSmartNav NAME=__hifSmartNav STYLE=display:none src=\"" + Util.GetScriptLocation(this.Context) + "SmartNav.htm\"></IFRAME>");
        page.RegisterClientScriptFileInternal(
"SmartNavIncludeScript""JScript""SmartNav.js");
    }
    
base.Render(output);  //调用基类(Control)的Render
}
protected virtual void Render(HtmlTextWriter writer);
 
Declaring Type: 
 System.Web.UI.Control 
 
Assembly: 
 System.Web, Version
=1.0.5000.0 
 

protected virtual void Render(HtmlTextWriter writer)
{
    
this.RenderChildren(writer);   //调用HtmlForm的重载实现
}
protected override void RenderChildren(HtmlTextWriter writer);
 
Declaring Type: 
 System.Web.UI.HtmlControls.HtmlForm 
 
Assembly: 
 System.Web, Version
=1.0.5000.0 
 

protected override void RenderChildren(HtmlTextWriter writer)
{
    
this.Page.OnFormRender(writer, this.UniqueID);  //准备客户端HTML对象,序列化ViewState成HTML表单域,并生成回传脚本
    base.RenderChildren(writer); //调用基类的过程,递归完成控件树的渲染
    this.Page.OnFormPostRender(writer, this.UniqueID); //继续输出新注册的客户端对象,回传脚本,以及注册的启动脚本
}
internal void OnFormRender(HtmlTextWriter writer, string formUniqueID);
 
Declaring Type: 
 System.Web.UI.Page 
 
Assembly: 
 System.Web, Version
=1.0.5000.0 
 

internal void OnFormRender(HtmlTextWriter writer, string formUniqueID)
{
    
if (this._fOnFormRenderCalled)
{
    
//禁止出现多个服务器表单
        throw new HttpException(HttpRuntime.FormatResourceString("Multiple_forms_not_allowed"));
    }
    
this._fOnFormRenderCalled = true;
    
this._inOnFormRender = true;
    
this.RenderHiddenFields(writer);   //生成注册的隐藏表单域
    if (this._viewStateToPersist != null)
    {
        
if (this._formatter == null)
        {
            
this.CreateLosFormatter(); 
        }
        writer.WriteLine();
        writer.Write(
"<input type=\"hidden\" name=\"");
        writer.Write("__VIEWSTATE");
        writer.Write(
"\" value=\"");
        
this._formatter.Serialize(writer, this._viewStateToPersist);    //序列化页面上保存的ViewState数据包
        writer.WriteLine("\" />");
    }
    
else
    {
        writer.WriteLine();
        writer.Write(
"<input type=\"hidden\" name=\"");
        writer.Write("__VIEWSTATE");
        writer.Write(
"\" value=\"\" />");
    }
    
if (this._fRequirePostBackScript)
    {
        
this.RenderPostBackScript(writer, formUniqueID);  //生成回传的客户端脚本
    }
    
this.RenderScriptBlock(writer, this._registeredClientScriptBlocks);   //生成注册过的客户端脚本块
}
protected virtual void RenderChildren(HtmlTextWriter writer);
 
Declaring Type: 
 System.Web.UI.Control 
 
Assembly: 
 System.Web, Version
=1.0.5000.0 
 

protected virtual void RenderChildren(HtmlTextWriter writer)
{
    
if (this._renderMethod != null)
    {
        
this._renderMethod(writer, this);
    }
    
else if (this._controls != null)
    {
        
int count = this._controls.Count;
        
for (int i = 0; i < count; i++)
        {
            
this._controls[i].RenderControl(writer);    //完成子控见的Render过程
        }
    }
}
internal void OnFormPostRender(HtmlTextWriter writer, string formUniqueID);
 
Declaring Type: 
 System.Web.UI.Page 
 
Assembly: 
 System.Web, Version
=1.0.5000.0 
 

internal void OnFormPostRender(HtmlTextWriter writer, string formUniqueID)
{
    
if (this._registeredArrayDeclares != null)    //生成客户端脚本数组定义
    {
        writer.WriteLine();
        writer.WriteLine(
"<script language=\"javascript\" type=\"text/javascript\">\r\n<!--");
        writer.Indent
++;
        IDictionaryEnumerator enumerator 
= this._registeredArrayDeclares.GetEnumerator();
        
while (enumerator.MoveNext())
        {
            writer.Write(
"var ");
            writer.Write(enumerator.Key);
            writer.Write(
" =  new Array(");
            IEnumerator enumerator2 
= ((ArrayList) enumerator.Value).GetEnumerator();
            
bool flag = true;
            
while (enumerator2.MoveNext())
            {
                
if (flag)
                {
                    flag 
= false;
                }
                
else
                {
                    writer.Write(
"");
                }
                writer.Write(enumerator2.Current);
            }
            writer.WriteLine(
");");
        }
        writer.Indent
++;
        writer.WriteLine(
"// -->\r\n</script>");
        writer.WriteLine();
    }
    
this.RenderHiddenFields(writer);   //生成注册的隐藏表单域
    if (this._fRequirePostBackScript && !this._fPostBackScriptRendered)
    {
        
this.RenderPostBackScript(writer, formUniqueID);   //生成回传脚本
    }
    
this.RenderScriptBlock(writer, this._registeredClientStartupScripts);  //生成注册的启动脚本
    this._inOnFormRender = false;
}
原文链接http://blog.csdn.net/yonghengdizhen/archive/2007/07/31/1719633.aspx
原文排版太难看了,故转过来。
posted @ 2008-04-09 22:16  stu_acer  阅读(599)  评论(0编辑  收藏