' 父类 Public Class BaseC Private _s1 As String Public Property S1() As String Get Return _s1 End Get Set(value As String) _s1 = value End Set End PropertyEnd Class' 子类 Public Class Sub1C Inherits BaseC Private _int1 As Integer Public Property S2() As Integer Get Return _int1 End Get Set(value As Integer) _int1 = value End Set End PropertyEnd Class' 用来存放数据的类 Public Class InfoClass Private _info As BaseC Public Sub New() End Sub Public Sub New(ByVal Info As BaseC) _info = Info End Sub Public Property Info() As BaseC Get Return _info End Get Set(value As BaseC) _info = value End Set End PropertyEnd Class下面是测试用例:Dim b1 As New BaseCDim t As New InfoClass(b1)' 正常 Dim str = FunctionUtils.Json.ConvertObjectToJson(t)Dim s1 As New Sub1CDim t As New InfoClass(s1)' 发生异常 Dim str = FunctionUtils.Json.ConvertObjectToJson(t)Dim s1 As Sub1C Dim b As BaseCs1 = New Sub1C b = CType(s1, BaseC)Dim t As New InfoClass(b)' 发生异常 Dim str = FunctionUtils.Json.ConvertObjectToJson(t)Dim b As BaseCb = New Sub1CDim t As New InfoClass(b)' 发生异常 Dim str = FunctionUtils.Json.ConvertObjectToJson(t)
还有一点 datacontractserializer 使用起来要标注给序列保存数据的属性标注datamember,C#里面 VB就不是很清楚了,如果VB有attribute,那么也要注意标注datamember,否则你反序列化之后,发现属性的值都是null的。比如 [Serialization] class A { [Datamember] public string ff{get;set;} }[Serialization] class B : A { [Datamember] public string yy{get;set;} }
VB.Net和C#一样,也有属性,只过格式不一样,是用<>而不是用[]。 我根据你说的,在代码加上了System.Runtime.Serialization命名空间下的<Serializable()>和<DataMember()>,但是还是出上面的错误。 代码如下:Imports System.Runtime.Serialization<Serializable()> _ Public Class BaseC <DataMember()> _ Private _s1 As String <DataMember()> _ Public Property S1() As String Get Return _s1 End Get Set(value As String) _s1 = value End Set End PropertyEnd Class<Serializable()> _ Public Class Sub1C Inherits BaseC <DataMember()> _ Private _int1 As Integer <DataMember()> _ Public Property S2() As Integer Get Return _int1 End Get Set(value As Integer) _int1 = value End Set End PropertyEnd Class<Serializable()> _ Public Class InfoClass Private _info As BaseC Public Sub New() End Sub Public Sub New(ByVal Info As BaseC) _info = Info End Sub <DataMember()> _ Public Property Info() As BaseC Get Return _info End Get Set(value As BaseC) _info = value End Set End PropertyEnd Class
我用C#的代码也试过了,也有同样的问题。 C#代码下:using System; using System.Runtime.Serialization;namespace TestCS.Serialization { [Serializable] public class BaseC { [DataMember] private string _s1; [DataMember] public string S1 { get { return _s1; } set { _s1 = value; } } } [Serializable] public class Sub1C : BaseC { [DataMember] private string _s2; [DataMember] public string S2 { get { return _s2; } set { _s2 = value; } } } [Serializable] public class InfoClass { [DataMember] private BaseC _info; public InfoClass() { } public InfoClass(BaseC b) { _info = b; } [DataMember] public BaseC Info { get { return _info; } set { _info = value; } } } } 请帮忙看一下。
楼主的问题是序列化类DataContractSerializer无法识别类型Sub1C,序列化时自动识别InfoClass 内的 Info为BaseC,但发现实际不是BaseC类的实例,就报异常。所以要告诉序列化类DataContractSerializer去识别未知类型为Sub1C BaseC c = new BaseC(); c.S1 = "1"; BaseC s = new Sub1C(); ((Sub1C)s).S1 = "2"; ((Sub1C)s).S2 = "3"; InfoClass ic = new InfoClass(s); List<Type> lt = new List<Type>(); lt.Add(typeof(Sub1C)); DataContractSerializer dcs = new DataContractSerializer(ic.GetType(), null); MemoryStream ms = new MemoryStream(); dcs.WriteObject(ms, ic);
上面发错了一句代码 DataContractSerializer dcs = new DataContractSerializer(ic.GetType(), lt);
2,InnerException是空。
3,有时间我把代码贴一下。
' 父类
Public Class BaseC Private _s1 As String Public Property S1() As String
Get
Return _s1
End Get
Set(value As String)
_s1 = value
End Set
End PropertyEnd Class' 子类
Public Class Sub1C
Inherits BaseC Private _int1 As Integer Public Property S2() As Integer
Get
Return _int1
End Get
Set(value As Integer)
_int1 = value
End Set
End PropertyEnd Class' 用来存放数据的类
Public Class InfoClass Private _info As BaseC Public Sub New()
End Sub Public Sub New(ByVal Info As BaseC)
_info = Info
End Sub Public Property Info() As BaseC
Get
Return _info
End Get
Set(value As BaseC)
_info = value
End Set
End PropertyEnd Class下面是测试用例:Dim b1 As New BaseCDim t As New InfoClass(b1)' 正常
Dim str = FunctionUtils.Json.ConvertObjectToJson(t)Dim s1 As New Sub1CDim t As New InfoClass(s1)' 发生异常
Dim str = FunctionUtils.Json.ConvertObjectToJson(t)Dim s1 As Sub1C
Dim b As BaseCs1 = New Sub1C
b = CType(s1, BaseC)Dim t As New InfoClass(b)' 发生异常
Dim str = FunctionUtils.Json.ConvertObjectToJson(t)Dim b As BaseCb = New Sub1CDim t As New InfoClass(b)' 发生异常
Dim str = FunctionUtils.Json.ConvertObjectToJson(t)
1.如果你序列化的是你自定义的类型,那么确保你的类型中的所有类型都被标记了可序列化,只要有一个没有标注可序列化,则整个类型的序列化就失败,也就是说,你举例中的S虽然继承自B,但是S也同样要标注序列化
2.反序列化的时候要注意序列化类型的解析,比如你的byte[]是类型B,那么你当前的域中必须要能解析类型B才可以,具体的可以去我的blog看看,就csdn的,里面有一篇专门讲了反序列化以及序列化的问题,以及传输这些序列化数据的情况。
VB好像没有attribute吧···
datacontractserializer 使用起来要标注给序列保存数据的属性标注datamember,C#里面
VB就不是很清楚了,如果VB有attribute,那么也要注意标注datamember,否则你反序列化之后,发现属性的值都是null的。比如
[Serialization]
class A
{
[Datamember]
public string ff{get;set;}
}[Serialization]
class B : A
{
[Datamember]
public string yy{get;set;}
}
VB.Net和C#一样,也有属性,只过格式不一样,是用<>而不是用[]。
我根据你说的,在代码加上了System.Runtime.Serialization命名空间下的<Serializable()>和<DataMember()>,但是还是出上面的错误。
代码如下:Imports System.Runtime.Serialization<Serializable()> _
Public Class BaseC <DataMember()> _
Private _s1 As String <DataMember()> _
Public Property S1() As String
Get
Return _s1
End Get
Set(value As String)
_s1 = value
End Set
End PropertyEnd Class<Serializable()> _
Public Class Sub1C
Inherits BaseC <DataMember()> _
Private _int1 As Integer <DataMember()> _
Public Property S2() As Integer
Get
Return _int1
End Get
Set(value As Integer)
_int1 = value
End Set
End PropertyEnd Class<Serializable()> _
Public Class InfoClass Private _info As BaseC Public Sub New()
End Sub Public Sub New(ByVal Info As BaseC)
_info = Info
End Sub <DataMember()> _
Public Property Info() As BaseC
Get
Return _info
End Get
Set(value As BaseC)
_info = value
End Set
End PropertyEnd Class
我用C#的代码也试过了,也有同样的问题。
C#代码下:using System;
using System.Runtime.Serialization;namespace TestCS.Serialization
{
[Serializable]
public class BaseC
{
[DataMember]
private string _s1; [DataMember]
public string S1
{
get { return _s1; }
set { _s1 = value; }
}
} [Serializable]
public class Sub1C : BaseC
{
[DataMember]
private string _s2; [DataMember]
public string S2
{
get { return _s2; }
set { _s2 = value; }
}
} [Serializable]
public class InfoClass
{
[DataMember]
private BaseC _info; public InfoClass()
{ } public InfoClass(BaseC b)
{
_info = b;
} [DataMember]
public BaseC Info
{
get { return _info; }
set { _info = value; }
}
}
}
请帮忙看一下。
c.S1 = "1";
BaseC s = new Sub1C();
((Sub1C)s).S1 = "2";
((Sub1C)s).S2 = "3";
InfoClass ic = new InfoClass(s);
List<Type> lt = new List<Type>();
lt.Add(typeof(Sub1C));
DataContractSerializer dcs = new DataContractSerializer(ic.GetType(), null);
MemoryStream ms = new MemoryStream();
dcs.WriteObject(ms, ic);
DataContractSerializer dcs = new DataContractSerializer(ic.GetType(), lt);