您的位置:首页 > 编程语言 > ASP

清清楚楚asp.net ( 三 ) :ViewState

2009-12-01 17:32 344 查看
ViewState概述

页面在初始化的时候,asp.net会在页面内建ViewState属性,我们可以将需要保存的数据放到视图状态的集合中,以达到在页面回发的时候保存数据的目的。

使用ViewState以前,需要注意以下内容:

1.ViewState依赖于字典集合。

2.ViewState中的每一项通过唯一的字符串名字进行索引。

我们在给视图集合的某个索引项赋值的时候,如果视图集合中存在该索引项,则赋值;如果没有,则改索引项将会被自动添加并赋值。

在尝试从视图集合中取出某个索引项的值的时候,如果视图集合中不存在此索引项的时候,将会抛出异常。

因此我们在取值的时候,通常会加个判断。

例如:




代码

if (ViewState["test"] != null)
{
int test = (int)ViewState["test"];
}

3.ViewState可以保存简单数据类型和自定义对象。

4.任何通过索引字符串从ViewState中取出来的数据都是Object类型,我们需要显式的将其转换成需要的类型,如上例。

使用ViewState的一个例子




html


<form id="form1" runat="server">


<div>


<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox><br/>


<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox><br/>


<asp:TextBox ID="TextBox3" runat="server"></asp:TextBox><br/>


<asp:TextBox ID="TextBox4" runat="server"></asp:TextBox><br/>


<asp:Button ID="Button1" runat="server" Text="Save" onclick="Button1_Click" />


<asp:Button ID="Button2" runat="server" Text="Restore" onclick="Button2_Click" />


<asp:Button ID="Button3" runat="server" Text="SaveWithDictionary" onclick="Button3_Click" />


<asp:Button ID="Button4" runat="server" Text="Display" onclick="Button4_Click" /><br />


<asp:Label ID="Label1" runat="server" Text=""></asp:Label>


</div>


</form>

将页面上所有的TextBox的值存入视图状态。




C#


protected void Button1_Click(object sender, EventArgs e)






{


SaveAllText(this.Controls);


}




private void SaveAllText(ControlCollection controls)






{


foreach (Control control in controls)






{


if (control is TextBox)






{


ViewState[control.ID] = ((TextBox)control).Text;


}


if (control.Controls != null)






{


SaveAllText(control.Controls);


}


}


}

从ViewState中取出各TextBox的值,并还原于页面。




C#


protected void Button2_Click(object sender, EventArgs e)






{


LoadAllText(this.Controls);


}




private void LoadAllText(ControlCollection controls)






{


foreach (Control control in controls)






{


if (control is TextBox && ViewState[control.ID] != null)






{


((TextBox)control).Text = (string)ViewState[control.ID];


}




if (control.Controls != null)






{


LoadAllText(control.Controls);


}


}


}

ViewState的实现过程:

ViewState在保存数据的时候,asp.net会将要保存的数据转换成比特流,以便能够保存在页面隐藏的input当中。

这个将数据转换成比特流的过程,也叫序列化。

在页面回发的时候,这些被序列化后的数据和正常数据一样被提交到服务器端。

在服务器端将这些数据反序列化以后,还原成ViewState的键值对形式,我们便可以通过ViewState的字符串索引来访问这些数据。

ViewState能够保存的数据类型:

从ViewState的实现过程中可以看出,使用ViewState保存数据的时候,被保存的数据需要进行序列化和反序列化的操作。

因此,某种数据类型是否能够保存在视图状态中,取决于这种数据类型能否被序列化和反序列化。

我们可以同在类声明前加上[Serializable]标记符,声明自定义对象是允许被序列化的。

例如:




代码

[Serializable]
public class Test
{ }

这样我们就声明了一个允许被序列化和反序列化的类。

因此我们msdn中看到一个类如果有Serializable特性,则表明这个类实例化后的对象便可以放入ViewState当中去。

下面这个例子是将一个Dictionary对象放入ViewState中的测试。Dictionary具有Serializable的特性,允许被序列化。

仍然使用上面例子中的html,在后台页面有如下代码。

将页面上所有TextBox的值存入ViewState中的一个Dictionary对象当中去。




C#


protected void Button3_Click(object sender, EventArgs e)






{


Dictionary<string, string> textToSave = new Dictionary<string, string>();


SaveAllTextWithDictionary(textToSave, this.Controls);


ViewState["ControlsText"] = textToSave;


}




private void SaveAllTextWithDictionary(Dictionary<string, string> textToSave, ControlCollection controls)






{


foreach (Control control in controls)






{


if (control is TextBox)






{


textToSave.Add(control.ID, ((TextBox)control).Text);


}


if (control.Controls != null)






{


SaveAllTextWithDictionary(textToSave, control.Controls);


}


}


}

遍历ViewState中索引项为"ControlsText"的项,其内容为一个Dictionary对象。




C#


protected void Button4_Click(object sender, EventArgs e)






{


DisplayAllText();


}




private void DisplayAllText()






{


if (ViewState["ControlsText"] != null)






{


Dictionary<string, string> savedText = (Dictionary<string, string>)ViewState["ControlsText"];




foreach (KeyValuePair<string, string> item in savedText)






{


this.Label1.Text += (string)item.Key + ":" + (string)item.Value + "<br/>";


}


}


}

ViewState的性能和安全

从ViewState的实现过程可以看出,试图状态通过Post的方式将数据内容存放到一个Base64位编码的单一字符串回传到服务器端,然后在反序列化回传的字符串并还原控件的状态。

因此使用ViewState势必会增大客户端和服务器端的数据传输量,在web应用当中,过大的数据传输两会影响系统性能和用户体验。

以下几种情况,应当尽量避免使用ViewState:

1.需要传送大量的数据时。

可以考虑采用数据库或者会话的形式进行数据的交互和保存。

2.传送的数据有较高的安全需求时。

ViewState虽然表面看起来是无顺序的一堆字符,但其实仍然是以明文的形式存放的,并没有进行加密处理。在客户端仍然可以获取或者篡改其值来欺骗服务器端。

3.控件的值是静态的时候。

4.控件的值需要在回传时重新加载数据。

本博客所有文章未注明转载,均为小弟原创。欢迎转载、演绎,但请保留如下签名(包括链接):本文出自博客园猪小广 。 不管水平高低,还请尊重小弟码字的辛苦。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: