我们在用.net开发web应用程序的时候经常会用到ViewState,真是个很有用的东东,那么ViewState到底是何方人氏那? 其实ViewState只是StateBag类的一个实例,所以我们平时看到的只是冰山的一角,现在我们就来探究一下下面的更大的冰山. *********************************************************************************************
NET Framework类库 StateBag 类 1. 概述 管理 ASP.NET 服务器控件(包括页)的视图状态。无法继承此类。 Control.ViewState 属性是 StateBag 类的实例。 有关此类型所有成员的列表,请参阅 StateBag 成员。 System.Object System.Web.UI.StateBag [定义][C#] public sealed class StateBag : IStateManager, IDictionary,ICollection, IEnumerable [线程安全] 此类型的所有公共静态(Visual Basic 中为 Shared)成员对多线程操作而言都是安全的。但不保证任何实例成员是线程安全的。 [备注] 页或控件的视图状态是该页或控件的累计属性值或视图。可以通过 Control.ViewState 属性访问此类。 此类是所有 HTML 和 Web 服务器控件的主存储机制。它将属性/值对存储为与控件关联的字符串。仅在为页请求执行 OnInit 方法后,它才跟踪这些属性的更改,并将更改保存到页或控件的视图状态。 在控件处理生存期的任何阶段可以从此类读取,但是当控件正在呈现时不应该向此类写入。 此类实现一个字典,可以像对待任何字典对象那样从其中添加或移除项。有关数据集合(如字典)的更多信息,请参见将数据组合到集合中。 [示例] 下面的示例说明一个具有 Text 和 FontSize 属性的复合 Label 控件。当在该控件上调用 Control.Render 方法时,这些属性保存到视图状态并从视图状态检索。 ------------------------------------------------------------------------------------------------------- [C#] // This control renders values stored in view state for Text and FontSize properties. using System; using System.Web; using System.Web.UI; namespace ViewStateControlSamples { public class Label: Control { // Add property values to view state with set; // retrieve them from view state with get. public String Text { get { return (String) ViewState["Text"]; } set { ViewState["Text"] = value; } } public int FontSize { get { return (int) ViewState["FontSize"]; } set { ViewState["FontSize"] = value; } } [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")] protected override void Render(HtmlTextWriter output) { output.Write("<font size=" + this.FontSize + ">" + this.Text + "</font>"); } } } --------------------------------------------------------------------------------------------- 2.构造函数 2.1 StateBag 构造函数 public StateBag(); 初始化 StateBag 类的新实例。这是此类的默认构造函数。 public StateBag(bool); 初始化 StateBag 类的新实例,该实例允许存储的状态值不区分大小写。 忽略大小写为 true;否则为 false。 3.属性 3.1 StateBag.Count 属性 获取 StateBag 对象中的 StateItem 对象数。 属性值 是 StateBag 对象中的项数。 实现 ICollection.Count 使用示例: ----------------------------------------------------- [C#] private string GetMruList(string selectedValue) { StateBag state = ViewState; if (state.Count > 0) { int upperBound = state.Count; string[] keys = new string[upperBound]; StateItem[] values = new StateItem[upperBound]; state.Keys.CopyTo(keys, 0); state.Values.CopyTo(values, 0); StringBuilder options = new StringBuilder(); for(int i = 0; i < upperBound; i++) { options.AppendFormat("<option {0} value={1}>{2}", (selectedValue == keys[i])?"selected":"", keys[i], values[i].Value); } return options.ToString(); } return ""; } ---------------------------------------------------------------------------- 3.2 StateBag.Item 属性 获取或设置在 StateBag 对象中存储的项的值。 [C#] 在 C# 中,该属性为 StateBag 类的索引器。 属性值 是 StateBag 对象中的指定项。 备注:使用该成员是为控件或页保存和检索视图状态值的最简单方法。 如果在设置该属性时项尚未存储在 StateBag 对象中,则项的键/值对将添加到集合中。在项上调用 TrackViewState 方法之前,如果将该属性设置为空引用(Visual Basic 中为 Nothing),则项从 StateBag 对象中被移除。否则,当将该属性设置为空引用 (Nothing) 时,将保存键以便能够跟踪项的视图状态。 示例:下面的示例说明一个将名称和值作为键/值对保存到 Control.ViewState 属性的属性。 (Control.ViewState 属性是 StateBag 类的实例。) --------------------------------------------------------------------------------- [C#] // Add property values to view state with set; // retrieve them from view state with get. public String Text { get { return (String) ViewState["Text"]; } set { ViewState["Text"] = value; } } ---------------------------------------------------------------------------------- 3.3 StateBag.Keys 属性 获取表示 StateBag 对象中的项的键集合。 属性值 是 键集合。 实现:IDictionary.Keys 备注:这些键是控件属性的名称。例如,如果在自定义的 Table 控件上创建 BGColor 属性,则在此集合中将创建一个 BGColor 项来表示 Table 控件的那个属性。 这些键与 StateBag 中为当前页或服务器控件存储的 StateItem 对象的名称相对应。 可以使用 StateBag.GetEnumerator 方法循环访问该集合。
[C#] 下面的示例说明如何使用 Keys 属性。 --------------------------------------------------------------------- [C#] private string GetMruList(string selectedValue) { StateBag state = ViewState; if (state.Count > 0) { int upperBound = state.Count; string[] keys = new string[upperBound]; StateItem[] values = new StateItem[upperBound]; state.Keys.CopyTo(keys, 0); state.Values.CopyTo(values, 0); StringBuilder options = new StringBuilder(); for(int i = 0; i < upperBound; i++) { options.AppendFormat("<option {0} value={1}>{2}", (selectedValue == keys[i])?"selected":"", keys[i], values[i].Value); } return options.ToString(); } return ""; } --------------------------------------------------------------------- 3.4 StateBag.Values 属性 获取存储在 StateBag 对象中的视图状态值的集合。 属性值 是 视图状态值的集合。 实现 :IDictionary.Values 备注 :这是包含指定页或控件中的所有 StateItem 对象的值的集合。可以使用 StateBag.GetEnumerator 方法循环访问这些值。 示例 :[C#] 下面的示例说明如何使用 Values 属性。 ---------------------------------------------------------------------- [C#] private string GetMruList(string selectedValue) { StateBag state = ViewState; if (state.Count > 0) { int upperBound = state.Count; string[] keys = new string[upperBound]; StateItem[] values = new StateItem[upperBound]; state.Keys.CopyTo(keys, 0); state.Values.CopyTo(values, 0); StringBuilder options = new StringBuilder(); for(int i = 0; i < upperBound; i++) { options.AppendFormat("<option {0} value={1}>{2}", (selectedValue == keys[i])?"selected":"", keys[i], values[i].Value); } return options.ToString(); } return ""; } ----------------------------------------------------------------------- 4.方法 4.1 StateBag.Add 方法 [概述]将新的 StateItem 对象添加到 StateBag 对象。如果项已经存在于 StateBag 中,则它更新项的值。 [调用形式][C#] public StateItem Add( string key, object value ); [参数] key StateItem 对象的属性名称。 value 要添加到 StateBag 的项的值。 [返回值] 返回表示添加到视图状态的对象的 StateItem 对象。 [异常] 异常类型 ArgumentException [条件] 当 key 为空或 key 中的字符数为 0 时发生。 [示例] [C#] 下面的示例说明如何使用 Add 方法。 -----------------------------------------------------------------------------------------------
[C#] void GotoButton_Click(Object sender, EventArgs e) { InvoiceRecord invoice = GetInvoice(GotoId.Text); GotoId.Text = ""; // Use the invoice Id as the key for the invoice // name in the StateBag. ViewState.Add(invoice.Id, invoice.Name); DisplayInvoice(invoice); selectedMruValue = invoice.Id; }
----------------------------------------------------------------------------------------------- 4.2 StateBag.Clear 方法 [概述]从当前 StateBag 对象中移除所有项。 [调用形式]public virtual void Clear(); [实现] IDictionary.Clear [示例] [C#] 下面的示例演示如何使用 Clear 方法 -------------------------------------------------------------------------------------------------
[C#] // Implement the SaveViewState method. If the StateBag // that stores the MyItem class's view state contains // a value for the message property and if the value // has changed since the TrackViewState method was last // called, all view state for this class is deleted, // using the StateBag.Clear method,and the new value is added. object IStateManager.SaveViewState() { // Check whether the message property exists in // the ViewState property, and if it does, check // whether it has changed since the most recent // TrackViewState method call. if( (!((IDictionary)_viewstate).Contains("message")) || (_viewstate.IsItemDirty("message"))) { { _viewstate.Clear(); // Add the _message property to the StateBag. _viewstate.Add("message", _message); } } return ((IStateManager)_viewstate).SaveViewState(); } -------------------------------------------------------------------------------------------------- 4.3 StateBag.GetEnumerator 方法 [概述]返回迭代 StateBag 中所存储的 StateItem 对象的所有键/值对的枚举数。 [调用形式] public virtual IDictionaryEnumerator GetEnumerator(); [ 返回值 ] 循环访问状态袋的枚举数。 [实现] IDictionary.GetEnumerator [示例(C#)] -------------------------------------------------------------------------------------------------- [C#] // Create a StateBag object to contain the view state // associated with the custom control named myControl. Use the // StateBag.GetEnumerator method to create an // IDictionaryEnumerator named myDictionaryEnumerator. ctlViewState1 ctlOne = new ctlViewState1(); StateBag myStateBag = new StateBag(); myStateBag = ctlOne.GetState(); IDictionaryEnumerator myDictionaryEnumerator = myStateBag.GetEnumerator(); ----------------------------------------------------------------------------------------------------- 4.4 StateBag.ICollection.CopyTo 方法 [概述]该成员支持 .NET Framework 结构,因此不适用于直接从代码中使用。 [调用方法][C#] void ICollection.CopyTo( Array array, int index ); 4.5 StateBag.IDictionary.Add 方法 [概述]该成员支持 .NET Framework 结构,因此不适用于直接从代码中使用。 [调用方法] [C#] void IDictionary.Add( object key, object value ); 4.6 StateBag.IDictionary.Contains 方法 [概述]该成员支持 .NET Framework 结构,因此不适用于直接从代码中使用。 [调用方法][C#] bool IDictionary.Contains( object key ); 4.7 StateBag.IDictionary.Remove 方法 [概述]该成员支持 .NET Framework 结构,因此不适用于直接从代码中使用。 [调用方法] [C#] void IDictionary.Remove( object key ); 4.8 StateBag.IEnumerable.GetEnumerator 方法 [概述]该成员支持 .NET Framework 结构,因此不适用于直接从代码中使用。 [调用方法][C#] IEnumerator IEnumerable.GetEnumerator(); 4.9 StateBag.IsItemDirty 方法 [概述]检查 StateBag 中存储的 StateItem 对象,计算自 Control.TrackViewState 调用后它是否已修改。 [调用方法][C#] public bool IsItemDirty( string key ); [参数] key 要检查的项的键。 [备注] 如果 StateBag 中不存在键参数,此方法还返回 false。 [示例][C#] 下面的示例演示如何使用 IsItemDirty 方法。 -------------------------------------------------------------------------------------------- [C#] // Implement the SaveViewState method. If the StateBag // that stores the MyItem class's view state contains // a value for the message property and if the value // has changed since the TrackViewState method was last // called, all view state for this class is deleted, // using the StateBag.Clear method,and the new value is added. object IStateManager.SaveViewState() { // Check whether the message property exists in // the ViewState property, and if it does, check // whether it has changed since the most recent // TrackViewState method call. if( (!((IDictionary)_viewstate).Contains("message")) || (_viewstate.IsItemDirty("message"))) { { _viewstate.Clear(); // Add the _message property to the StateBag. _viewstate.Add("message", _message); } } return ((IStateManager)_viewstate).SaveViewState(); } -------------------------------------------------------------------------------------------- 4.10 StateBag.IStateManager.LoadViewState 方法 该成员支持 .NET Framework 结构,因此不适用于直接从代码中使用。 [调用方法][C#] void IStateManager.LoadViewState( object state ); 4.11 StateBag.IStateManager.SaveViewState 方法 该成员支持 .NET Framework 结构,因此不适用于直接从代码中使用。 [调用方法][C#] object IStateManager.SaveViewState(); 4.12 StateBag.IStateManager.TrackViewState 方法 该成员支持 .NET Framework 结构,因此不适用于直接从代码中使用。 [调用方法][C#] void IStateManager.TrackViewState(); 4.13 StateBag.Remove 方法 [概述]将指定的密钥/值对从 StateBag 对象中移除。 [调用方法][C#] public void Remove( string key ); [参数] key 要移除的项 [示例][C#] 下面的示例说明如何使用 Remove 方法。 -------------------------------------------------------------------------------------- [C#] void MovePiece(string fromPosition, string toPosition) { StateBag bag = ViewState; object piece = bag[fromPosition]; if (piece != null) { bag.Remove(fromPosition); bag.Add(toPosition, piece); RenderBoard(); } else { throw new InvalidPositionException("There is no game piece at the \"from\" position."); } } -------------------------------------------------------------------------------------- 4.14 StateBag.SetItemDirty 方法 该成员支持 .NET Framework 结构,因此不适用于直接从代码中使用。 [调用方法][C#] public void SetItemDirty( string key, bool dirty );
*********************************************************************************************** 呵呵,是不是一个庞大的类? 学习到这里,我们可以看到,StateBag的内部是一个一个的StateItem.现在我们就看一下这个庞然大物的一根根骨头吧. *********************************************************************************************
.NET Framework 类库 StateItem 类 1.类的信息 [概述]表示当视图状态信息在 Web 请求间持续时保存在 StateBag 类中的项。无法继承此类。 有关此类型所有成员的列表,请参阅 StateItem 成员。 System.Object System.Web.UI.StateItem [类型][C#] public sealed class StateItem
[线程安全] 此类型的所有公共静态(Visual Basic 中为 Shared)成员是线程安全的。但不保证任何实例成员是线程安全的。
[备注] 视图状态是页或 ASP.NET 服务器控件属性值的累计,通过隐藏字段发送到请求浏览器。
可以使用 Item 属性或 Add 方法,将 StateItem 对象显式添加到 ASP.NET 服务器控件的 StateBag。StateBag 然后跟踪它存储的所有项的更改。StateItem 对象的所有更改都反映在其 IsDirty 属性中。这些更改在服务器控件处理的保存视图状态阶段,刚好在控件呈现到页之前,通过 SaveViewState 方法调用进行保存。有关更多信息,请参见控件执行生命周期。
[示例] [C#] 下面的示例使用 StateItem 类的 Value 和 IsDirty 属性保存简单的自定义 ASP.NET 服务器控件类 FirstCustomControl 的状态。在页发送到服务器后,IsDirty 属性检查项是否被修改过。该状态值可通过访问 Value 属性来显示。 ------------------------------------------------------------------------------------------------------ [C#] // Create a function that iterates through the view-state // values stored for this class and returns the // results as a string. public string EnumerateViewState() { string keyName,keyValue; string result = String.Empty; StateItem myStateItem; IDictionaryEnumerator myDictionaryEnumerator = _viewstate.GetEnumerator(); while(myDictionaryEnumerator.MoveNext()) { keyName = (string)myDictionaryEnumerator.Key; myStateItem = (StateItem)myDictionaryEnumerator.Value; keyValue = (string)myStateItem.Value; result = result + "<br>ViewState[" + keyName + "] = " + keyValue; } return result; } ------------------------------------------------------------------------------------------------------ 2.属性 2.1 StateItem.IsDirty 属性 [概述]获取或设置一个值,该值指示 StateItem 对象是否已修改。 [定义][C#] public bool IsDirty {get; set;} [属性值] 如果存储的 StateItem 对象已修改,则为 true;否则为 false。
2.2 StateItem.Value 属性 [概述]获取或设置存储在 StateBag 对象中的 StateItem 对象的值。 [定义] [C#] public object Value {get; set;} [属性值] 存储在 StateBag 对象中的 StateItem 的值。 [示例] [C#] -------------------------------------------------------------------------------- // Create a function that iterates through the view-state // values stored for this class and returns the // results as a string. public string EnumerateViewState() { string keyName,keyValue; string result = String.Empty; StateItem myStateItem; IDictionaryEnumerator myDictionaryEnumerator = _viewstate.GetEnumerator(); while(myDictionaryEnumerator.MoveNext()) { keyName = (string)myDictionaryEnumerator.Key; myStateItem = (StateItem)myDictionaryEnumerator.Value; keyValue = (string)myStateItem.Value; result = result + "<br>ViewState[" + keyName + "] = " + keyValue; } return result; }
---------------------------------------------------------------------------------- ********************************************************************************** ok,现在我们对ViewState的理解应该深入了很多,这对我们以后的编程很有好处哟  
|