积极答复者
序列化和反序列化一个继承DataTable的问题

问题
-
定义了一个DataTable类myTable,继承自DataTable。里面增加了一个自己的类,用来存放一些数据。定义如下:
[Serializable()]
public class myTable:DataTable
{
private UpdateParm _updateParm = new UpdateParm();
public UpdateParm updateParm
{
get { return _updateParm; }
set { _updateParm = value; }
}public DataTableBase() :base(){ }
protected DataTableBase(SerializationInfo info, StreamingContext context) : base(info, context) { }
}数据访问层中,从数据库检索数据到myTable1(myTable的一个实例)中,并且设置myTable1.updateParm.mytext="测试值"。mytext是UpdateParm 类的一个属性。
序列化脚本如下,返回byte[]
byte[] bArrayResult = null;
myTable1.RemotingFormat = SerializationFormat.Binary;
MemoryStream ms = new MemoryStream();
IFormatter bf = new BinaryFormatter();
bf.Serialize(ms, myTable1);
bArrayResult = ms.ToArray();
ms.Close();反序列化脚本:
MemoryStream ms = new MemoryStream(bUserData);
IFormatter bf = new BinaryFormatter();
object obj = bf.Deserialize(ms);
bTable = (myTable)obj;
ms.Close();反序列化后,myTable1数据正常,但是myTable1.updateParm.mytext的值却没有传递成功,请帮忙分析一下是什么原因?
答案
-
由于DataTable实现了ISerializable接口,从而调用了自定义序列化机制。由于UpdateParm 是新的类型,肯定不为DataTable所识别故不序列化。
具体步骤:1、重写GetObjectData方法;
2、为了支持匹配的反序列化,要提供一个反序列化构造函数MyTable(SerializationInfo info, StreamingContext context)。
以下代码在vs2008上测试通过,支持UpdateParm的序列化和反序列化。代码请参考:
[Serializable]
public class MyTable : DataTable
{
private UpdateParm _updateParm = new UpdateParm();
public UpdateParm updateParm
{
get { return _updateParm; }
set { _updateParm = value; }
}[OnSerializing]
internal void OnSerializing(StreamingContext context)
{
string abc = "MyTable";
}
public MyTable() : base() { }public MyTable(SerializationInfo info, StreamingContext context):base(info,context)
{
updateParm = (UpdateParm)info.GetValue("updateParm",typeof(UpdateParm));
}public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context); //保持对Table内的类型序列化
info.AddValue("updateParm", updateParm, typeof(UpdateParm)); //新增对新类型支持
}
}
[Serializable]
public class UpdateParm
{
public string MyText { get; set; }[OnSerializing]
internal void OnSerializing(StreamingContext context)
{
//默认情况下不进入该方法调用,说明没有对UpdateParm序列化
//进行上述的两个步骤后,该事件被触发
string abc = "UpdateParm";
}
}- 已标记为答案 Andrew_ZhuModerator 2009年7月10日 6:37
全部回复
-
由于DataTable实现了ISerializable接口,从而调用了自定义序列化机制。由于UpdateParm 是新的类型,肯定不为DataTable所识别故不序列化。
具体步骤:1、重写GetObjectData方法;
2、为了支持匹配的反序列化,要提供一个反序列化构造函数MyTable(SerializationInfo info, StreamingContext context)。
以下代码在vs2008上测试通过,支持UpdateParm的序列化和反序列化。代码请参考:
[Serializable]
public class MyTable : DataTable
{
private UpdateParm _updateParm = new UpdateParm();
public UpdateParm updateParm
{
get { return _updateParm; }
set { _updateParm = value; }
}[OnSerializing]
internal void OnSerializing(StreamingContext context)
{
string abc = "MyTable";
}
public MyTable() : base() { }public MyTable(SerializationInfo info, StreamingContext context):base(info,context)
{
updateParm = (UpdateParm)info.GetValue("updateParm",typeof(UpdateParm));
}public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context); //保持对Table内的类型序列化
info.AddValue("updateParm", updateParm, typeof(UpdateParm)); //新增对新类型支持
}
}
[Serializable]
public class UpdateParm
{
public string MyText { get; set; }[OnSerializing]
internal void OnSerializing(StreamingContext context)
{
//默认情况下不进入该方法调用,说明没有对UpdateParm序列化
//进行上述的两个步骤后,该事件被触发
string abc = "UpdateParm";
}
}- 已标记为答案 Andrew_ZhuModerator 2009年7月10日 6:37