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

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

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

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

        test[
-1= TextBox1.Text;

        ViewState[
"VIEW_TEST"= test;
    }

下面再看一下自定义类Test的实现:
[SerializableAttribute]
class  Test
{
    
private IList list;

    
public Test()
    
{
        list 
= new ArrayList();
    }


    
public object this[int index]
    
{
        
get
        
{
            
if (index >= list.Count)
            
{
                
return null;
            }

            
return list[index];
        }

        
set
        
{
            list.Add(value);
        }


    }

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

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


    
public object this[int index]
    
{
        
get
        
{
            
if (index >= Rows.Count)
            
{
                
return null;
            }

            
return Rows[index]["name"];
        }

        
set
        
{
            DataRow row 
= NewRow();
            row[
"name"= value;
            Rows.Add(row);
        }

    }

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


    
public object this[int index]
    
{
        
get
        
{
            
if (index >= Rows.Count)
            
{
                
return null;
            }

            
return Rows[index]["name"];
        }

        
set
        
{
            DataRow row 
= NewRow();
            row[
"name"= value;
            Rows.Add(row);
        }

    }


    
public Test(SerializationInfo info, StreamingContext context)
    
{
        DataColumn col 
= new DataColumn();
        col.DataType 
= typeof(string);
        col.ColumnName 
= "name";
        
this.Columns.Add(col);

        ArrayList list 
= info.GetValue("list"typeof(ArrayList)) as ArrayList;
        
foreach (string value in list)
        
{
            DataRow row 
= NewRow();
            row[
"name"= value;
            Rows.Add(row);
        }

    }


    
public void GetObjectData(SerializationInfo info, StreamingContext context)
    
{
        ArrayList list 
= new ArrayList();
        
foreach (DataRow row in this.Rows)
        
{
            list.Add(row[
"name"]);
        }
 
        info.AddValue(
"list", list);
    }


}
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,如需转载请自行联系原作者



相关文章
|
2月前
|
存储 C#
C#中的序列化和反序列化
C#中的序列化和反序列化
12 0
|
2月前
|
存储 C#
C#中的序列化和反序列化案例
C#中的序列化和反序列化案例
14 0
|
5月前
|
XML 存储 JSON
C# 对象存储 (轻松实现序列化 | Xml | Json | 加密 | 压缩 | 注册表 | Redis)
开发时经常会遇到需要保存配置的情况,最常见的实现方式是将对象序列化成Json,再写入文件并保存到本地磁盘。 本文将使用开源库**ApeFree.DataStore**来替换原有的对象存储过程,实现一个可以随意切换存储方式的对象存储方法。 ApeFree.DataStore是一款可配置的对象存储库,支持在不同平台/介质中对内存中的对象进行存储与还原(如本地存储、注册表存储)。支持配置序列化格式(如Json、Xml),支持配置压缩算法(如GZip、Defalte),支持配置加密算法(如AES、RSA)。
69 0
C# 对象存储 (轻松实现序列化 | Xml | Json | 加密 | 压缩 | 注册表 | Redis)
|
5月前
|
XML 存储 JSON
C# | 使用Json序列化对象时忽略只读的属性
将对象序列化成为Json字符串是一个使用频率非常高的功能。Json格式具有很高的可读性,同时相较于XML更节省空间。 在开发过程中经常会遇到需要保存配置的场景,比如将配置信息保存在配置类型的实例中,再将这个对象序列化成为Json字符串并保存。当需要加载配置时,则是读取Json格式的字符串再将其还原成配置对象。在序列化的过程中,默认会将所有公开的属性和字段都序列化进入Json字符串中,这其中也会包含只读的属性或字段,而只读的属性和字段在反序列化的过程中其实是无意义的,也就是说这一部分存储是多余的。 本文将讲解如何在执行Json序列化时,忽略掉那些只读的属性和字段。
58 0
C# | 使用Json序列化对象时忽略只读的属性
|
6月前
|
JSON JavaScript 前端开发
c#JSON序列化&反序列化
JSON(全称为JavaScript ObjectNotation) 是一种轻量级的数据交换格式。它是基于JavaScript语法标准的一个子集。JSON采用完全独立于语言的文本格式,可以很容易在各种网络、平台和程序之间传输。JSON的语法很简单,易于人阅读和编写,同时也易于机器解析和生成。
40 0
|
8月前
|
XML 存储 C#
C#三十一 序列化与反序列化
C#三十一 序列化与反序列化
24 0
|
10月前
|
前端开发 API 数据库
C# Abp框架入门系列文章(一)(下)
C# Abp框架入门系列文章(一)(下)
319 0
|
10月前
|
SQL 开发框架 缓存
C# Abp框架入门系列文章(一)(上)
C# Abp框架入门系列文章(一)
247 0
|
前端开发 C# 开发工具
想用C# .Net生成行为验证码,还得看这篇文章
为了增强网站的安全性,我们在网站的登录模块或信息输入模块加入了验证码功能,那么在C# .Net中如何实现验证码呢?本文借助KgCaptcha实现了这个功能。
想用C# .Net生成行为验证码,还得看这篇文章
|
XML JSON JavaScript
30天C#基础巩固-----序列化,集合
30天C#基础巩固-----序列化,集合
96 0
30天C#基础巩固-----序列化,集合