C#强化系列文章一:ViewState使用兼谈序列化

ViewState的使用比较简单,一两句话就可以了。
赋值:ViewState[key] = value;
取值:value = ViewState[key];

最主要的作用就是可以在当前页面保存值,ASP.NET的页面状态维护就是使用ViewState来实现的,基本上每一个ASPX页面都可以看到如下类似的html代码:
C#强化系列文章一:ViewState使用兼谈序列化<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTkwNjc4NTIwMWRkyv4ncofW5vaWXdXRtXfXn3RYQR4=" />
C#强化系列文章一:ViewState使用兼谈序列化
也就是说ViewState中的值实际上都是通过一个hidden来保存的,hidden的name为__VIEWSTATE,那么如果页面上有另外一个控件的名称也叫:__VIEWSTATE的话,会导致页面出错。
其实在我们进行页面开发或者进行自定义控件开发的时候,都可以使用ViewState,很方便。

ViewState是ASP.NET中特有的,相对于Session来说,它保存的值只能在当前页面使用,并且保存的只能是已经序列化的类,比如.NET中的strings, integers, Booleans, arrays, ArrayList, hashtable,DataTable等。
那么如何将自定义的类放入ViewState中呢,这个就涉及到如下所说的序列化的问题了:
序列化简单来说就是把一个对象转化成一种可以持久保存的数据,当下次需要使用时再把之前保存的数据反序列化成一个对象。
当然在.NET中提供了简便的方法进行序列化的操作。
下面我以一个简单的例子来说明
将自定义类Test保存到viewstate中的按钮事件代码:
C#强化系列文章一:ViewState使用兼谈序列化    protected void Button1_Click(object sender, EventArgs e)
C#强化系列文章一:ViewState使用兼谈序列化    
{
C#强化系列文章一:ViewState使用兼谈序列化        Test test 
= ViewState["VIEW_TEST"as Test;
C#强化系列文章一:ViewState使用兼谈序列化        
if (test == null)
C#强化系列文章一:ViewState使用兼谈序列化        
{
C#强化系列文章一:ViewState使用兼谈序列化            test 
= new Test();
C#强化系列文章一:ViewState使用兼谈序列化        }

C#强化系列文章一:ViewState使用兼谈序列化        test[
-1= TextBox1.Text;
C#强化系列文章一:ViewState使用兼谈序列化
C#强化系列文章一:ViewState使用兼谈序列化        ViewState[
"VIEW_TEST"= test;
C#强化系列文章一:ViewState使用兼谈序列化    }

下面再看一下自定义类Test的实现:
C#强化系列文章一:ViewState使用兼谈序列化[SerializableAttribute]
C#强化系列文章一:ViewState使用兼谈序列化
class Test
C#强化系列文章一:ViewState使用兼谈序列化
{
C#强化系列文章一:ViewState使用兼谈序列化    
private IList list;
C#强化系列文章一:ViewState使用兼谈序列化
C#强化系列文章一:ViewState使用兼谈序列化    
public Test()
C#强化系列文章一:ViewState使用兼谈序列化    
{
C#强化系列文章一:ViewState使用兼谈序列化        list 
= new ArrayList();
C#强化系列文章一:ViewState使用兼谈序列化    }

C#强化系列文章一:ViewState使用兼谈序列化
C#强化系列文章一:ViewState使用兼谈序列化    
public object this[int index]
C#强化系列文章一:ViewState使用兼谈序列化    
{
C#强化系列文章一:ViewState使用兼谈序列化        
get
C#强化系列文章一:ViewState使用兼谈序列化        
{
C#强化系列文章一:ViewState使用兼谈序列化            
if (index >= list.Count)
C#强化系列文章一:ViewState使用兼谈序列化            
{
C#强化系列文章一:ViewState使用兼谈序列化                
return null;
C#强化系列文章一:ViewState使用兼谈序列化            }

C#强化系列文章一:ViewState使用兼谈序列化            
return list[index];
C#强化系列文章一:ViewState使用兼谈序列化        }

C#强化系列文章一:ViewState使用兼谈序列化        
set
C#强化系列文章一:ViewState使用兼谈序列化        
{
C#强化系列文章一:ViewState使用兼谈序列化            list.Add(value);
C#强化系列文章一:ViewState使用兼谈序列化        }

C#强化系列文章一:ViewState使用兼谈序列化
C#强化系列文章一:ViewState使用兼谈序列化    }

C#强化系列文章一:ViewState使用兼谈序列化}
特别注意第一行的SerializableAttribute属性,指定这个属性后就代表此类是可以序列化的(具体序列化的过程都是由.NET内部进行的),那么我们就可以把此类放入ViewState中了,如果没有指定SerializableAttribute属性的话,放入ViewState时就会报错。

以上所示是序列化的第一种方式:基本序列化,也是比较简单的一种,如果是复杂情况就要使用下面所说的第二种序列化的方式:自定义序列化
假设我们的Test类需要从DataTable继承:
C#强化系列文章一:ViewState使用兼谈序列化[SerializableAttribute]
C#强化系列文章一:ViewState使用兼谈序列化
class Test : DataTable
C#强化系列文章一:ViewState使用兼谈序列化
{
C#强化系列文章一:ViewState使用兼谈序列化    
public Test()
C#强化系列文章一:ViewState使用兼谈序列化    
{
C#强化系列文章一:ViewState使用兼谈序列化        DataColumn col 
= new DataColumn();
C#强化系列文章一:ViewState使用兼谈序列化        col.DataType 
= typeof(string);
C#强化系列文章一:ViewState使用兼谈序列化        col.ColumnName 
= "name";
C#强化系列文章一:ViewState使用兼谈序列化        
this.Columns.Add(col);
C#强化系列文章一:ViewState使用兼谈序列化    }

C#强化系列文章一:ViewState使用兼谈序列化
C#强化系列文章一:ViewState使用兼谈序列化    
public object this[int index]
C#强化系列文章一:ViewState使用兼谈序列化    
{
C#强化系列文章一:ViewState使用兼谈序列化        
get
C#强化系列文章一:ViewState使用兼谈序列化        
{
C#强化系列文章一:ViewState使用兼谈序列化            
if (index >= Rows.Count)
C#强化系列文章一:ViewState使用兼谈序列化            
{
C#强化系列文章一:ViewState使用兼谈序列化                
return null;
C#强化系列文章一:ViewState使用兼谈序列化            }

C#强化系列文章一:ViewState使用兼谈序列化            
return Rows[index]["name"];
C#强化系列文章一:ViewState使用兼谈序列化        }

C#强化系列文章一:ViewState使用兼谈序列化        
set
C#强化系列文章一:ViewState使用兼谈序列化        
{
C#强化系列文章一:ViewState使用兼谈序列化            DataRow row 
= NewRow();
C#强化系列文章一:ViewState使用兼谈序列化            row[
"name"= value;
C#强化系列文章一:ViewState使用兼谈序列化            Rows.Add(row);
C#强化系列文章一:ViewState使用兼谈序列化        }

C#强化系列文章一:ViewState使用兼谈序列化    }

C#强化系列文章一:ViewState使用兼谈序列化}
那么再把这个类放入ViewState的话就会报错:此页的状态信息无效,可能已损坏,主要是因为它的父类DataTable中的DataRow和DataColumn等是不可序列化的,我们就需要把这个类改造成如下形式:
C#强化系列文章一:ViewState使用兼谈序列化[SerializableAttribute]
C#强化系列文章一:ViewState使用兼谈序列化
class Test : DataTable, System.Runtime.Serialization.ISerializable
C#强化系列文章一:ViewState使用兼谈序列化
{
C#强化系列文章一:ViewState使用兼谈序列化    
public Test()
C#强化系列文章一:ViewState使用兼谈序列化    
{
C#强化系列文章一:ViewState使用兼谈序列化        DataColumn col 
= new DataColumn();
C#强化系列文章一:ViewState使用兼谈序列化        col.DataType 
= typeof(string);
C#强化系列文章一:ViewState使用兼谈序列化        col.ColumnName 
= "name";
C#强化系列文章一:ViewState使用兼谈序列化        
this.Columns.Add(col);
C#强化系列文章一:ViewState使用兼谈序列化    }

C#强化系列文章一:ViewState使用兼谈序列化
C#强化系列文章一:ViewState使用兼谈序列化    
public object this[int index]
C#强化系列文章一:ViewState使用兼谈序列化    
{
C#强化系列文章一:ViewState使用兼谈序列化        
get
C#强化系列文章一:ViewState使用兼谈序列化        
{
C#强化系列文章一:ViewState使用兼谈序列化            
if (index >= Rows.Count)
C#强化系列文章一:ViewState使用兼谈序列化            
{
C#强化系列文章一:ViewState使用兼谈序列化                
return null;
C#强化系列文章一:ViewState使用兼谈序列化            }

C#强化系列文章一:ViewState使用兼谈序列化            
return Rows[index]["name"];
C#强化系列文章一:ViewState使用兼谈序列化        }

C#强化系列文章一:ViewState使用兼谈序列化        
set
C#强化系列文章一:ViewState使用兼谈序列化        
{
C#强化系列文章一:ViewState使用兼谈序列化            DataRow row 
= NewRow();
C#强化系列文章一:ViewState使用兼谈序列化            row[
"name"= value;
C#强化系列文章一:ViewState使用兼谈序列化            Rows.Add(row);
C#强化系列文章一:ViewState使用兼谈序列化        }

C#强化系列文章一:ViewState使用兼谈序列化    }

C#强化系列文章一:ViewState使用兼谈序列化
C#强化系列文章一:ViewState使用兼谈序列化    
public Test(SerializationInfo info, StreamingContext context)
C#强化系列文章一:ViewState使用兼谈序列化    
{
C#强化系列文章一:ViewState使用兼谈序列化        DataColumn col 
= new DataColumn();
C#强化系列文章一:ViewState使用兼谈序列化        col.DataType 
= typeof(string);
C#强化系列文章一:ViewState使用兼谈序列化        col.ColumnName 
= "name";
C#强化系列文章一:ViewState使用兼谈序列化        
this.Columns.Add(col);
C#强化系列文章一:ViewState使用兼谈序列化
C#强化系列文章一:ViewState使用兼谈序列化        ArrayList list 
= info.GetValue("list"typeof(ArrayList)) as ArrayList;
C#强化系列文章一:ViewState使用兼谈序列化        
foreach (string value in list)
C#强化系列文章一:ViewState使用兼谈序列化        
{
C#强化系列文章一:ViewState使用兼谈序列化            DataRow row 
= NewRow();
C#强化系列文章一:ViewState使用兼谈序列化            row[
"name"= value;
C#强化系列文章一:ViewState使用兼谈序列化            Rows.Add(row);
C#强化系列文章一:ViewState使用兼谈序列化        }

C#强化系列文章一:ViewState使用兼谈序列化    }

C#强化系列文章一:ViewState使用兼谈序列化
C#强化系列文章一:ViewState使用兼谈序列化    
public void GetObjectData(SerializationInfo info, StreamingContext context)
C#强化系列文章一:ViewState使用兼谈序列化    
{
C#强化系列文章一:ViewState使用兼谈序列化        ArrayList list 
= new ArrayList();
C#强化系列文章一:ViewState使用兼谈序列化        
foreach (DataRow row in this.Rows)
C#强化系列文章一:ViewState使用兼谈序列化        
{
C#强化系列文章一:ViewState使用兼谈序列化            list.Add(row[
"name"]);
C#强化系列文章一:ViewState使用兼谈序列化        }
 
C#强化系列文章一:ViewState使用兼谈序列化        info.AddValue(
"list", list);
C#强化系列文章一:ViewState使用兼谈序列化    }

C#强化系列文章一:ViewState使用兼谈序列化
C#强化系列文章一:ViewState使用兼谈序列化}
1、实现ISerializable接口
2、实现GetObjectData方法,这个方法中就是把要序列化的对象放入info中,特别注意放入info中的对象本身必须是可以序列化的,如果放入一个DataRow对象,就会报错:未标记为可序列化
3、实现public Test(SerializationInfo info, StreamingContext context) 构造函数,这个函数就是一个反序列化的操作,把info中的对象取出来

经过上面的改造之后,就可以把这个Test对象放入ViewState中了



    本文转自永春博客园博客,原文链接:http://www.cnblogs.com/firstyi/archive/2007/11/20/965957.html,如需转载请自行联系原作者


上一篇:看见新力量NO.03|专访昇暘光學创始人李文宗


下一篇:看见新力量NO.04|专访PIX Moving创始人喻川