这是我的旧类图(简化)。
public class Main
Public Property ListOfA As ClassACollection
End Class
Public Class ClassBase
End Class
Public Class ClassA
Inherits ClassBase
End Class
Public Class ClassACollection
Inherits System.Collections.ObjectModel.Collection(Of ClassA)
End Class
Public Class ClassB
Inherits ClassBase
End Class
Public Class ClassBCollection
Inherits System.Collections.ObjectModel.Collection(Of ClassB)
End Class
当我使用Main
序列化类DataContractSerializer
时,我得到了这样的XML:
<Main>
<ListOfA>
<ClassA>
.....
</ClassA>
<ClassA>
.....
</ClassA>
</ListOfA>
</Main>
最近我删除了ClassA
和ClassB
,因为它们完全相同!我删除了两个集合以替换它们:
public class Main
Public Property ListOfA As ClassBaseCollection
End Class
Public Class ClassBaseCollection
Inherits System.Collections.ObjectModel.Collection(Of ClassBase)
End Class
但是现在当我尝试反序列化XML时,集合ListOfA
已创建但始终为空!反序列化期间没有出错。
我尝试使用DataContractResolver
,但函数ResolveName
永远不会调用ClassA
或ClassB
。
Dim dc As New Runtime.Serialization.DataContractSerializer(GetType(Main), Nothing, Integer.MaxValue, False, True, Nothing, New MyResolver())
Private Class MyResolver
Inherits Runtime.Serialization.DataContractResolver
Public Overrides Function ResolveName(typeName As String, typeNamespace As String, declaredType As System.Type, knownTypeResolver As System.Runtime.Serialization.DataContractResolver) As System.Type
If typeName.Equals("ClassA") OrElse typeName.Equals("ClassB") Then
Return GetType(ClassBase)
Else
'Defer to the known type resolver
Return knownTypeResolver.ResolveName(typeName, typeNamespace, Nothing, Nothing)
End If
End Function
End Class
DataContractResolver
能够做到我想要的好方法吗?
如果是,我需要其他东西才能使DataContractResolver
工作吗?
感谢您的帮助!
更新
我在项目中添加了ClassA
和ClassB
来进行以下测试:
- 我试图将它们作为已知数据类型放在DataContractSerializer
构造函数中
- 我在ClassBaseCollection`上尝试了KnownTypeAttribute
。
在这两种情况下,仍然没有为ResolveName
和ClassA
调用ClassB
。
我尝试使用从IDataContractSurrogate
派生的类并转换函数GetDataContractType
中的类型,此函数不会调用ClassA
和ClassB
。
更新#2: 最后,我没有找到任何办法去做我想要的。我需要查看文件版本,并在序列化之前用XML中的新标记替换旧标记。防爆。 :
data = data.Replace("<ClassA>", "<ClassBase>")
...
这不是我第一个问题的答案,而是一种解决方法。
答案 0 :(得分:1)
但是现在当我尝试反序列化XML时,集合
ListOfA
就是 创造但总是空的!反序列化期间没有出错。
在msdn documentation on Data Contract Versioning中,您可以找到有关ListOfA
为空的原因的信息。调整后版本的反序列化引擎无法解释ClassA
或ClassB
,因此会丢弃此数据。
我认为您使用Data Contract Resolver进行了正确的跟踪。
数据合约解析程序允许您配置已知类型 动态。 序列化时需要已知类型或 反序列化数据合同不期望的类型。
由于您未在DataContractSerializer
constructor的已知数据类型参数中指定ClassA
和ClassB
,因此不会为它们调用ResolveName()
。有关已知数据类型的更多信息,请check the msdn documentation。这意味着为了正确地反序列化这些旧类,您仍然需要包含它们以实现向后兼容。