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

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
<stringstring> textToSave = new Dictionary<stringstring>();
        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
<stringstring> savedText = (Dictionary<stringstring>)ViewState["ControlsText"];

            
foreach (KeyValuePair<stringstring> 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.控件的值需要在回传时重新加载数据。

 

 


 

 


本博客所有文章未注明转载,均为小弟原创。欢迎转载、演绎,但请保留如下签名(包括链接):本文出自博客园猪小广  。 不管水平高低,还请尊重小弟码字的辛苦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值