.net 在DataContractSerializer中将删除的类型反序列化为新类型(旧基类)
这是我的旧类图(简化) 当我用.net 在DataContractSerializer中将删除的类型反序列化为新类型(旧基类),.net,vb.net,datacontractserializer,.net,Vb.net,Datacontractserializer,这是我的旧类图(简化) 当我用DataContractSerializer序列化类Main时,我得到了如下XML: <Main> <ListOfA> <ClassA> ..... </ClassA> <ClassA> ..... </ClassA> </ListOfA> </Main> 但是现在,当我尝试反序列化XML时,会创建集合Li
DataContractSerializer
序列化类Main
时,我得到了如下XML:
<Main>
<ListOfA>
<ClassA>
.....
</ClassA>
<ClassA>
.....
</ClassA>
</ListOfA>
</Main>
但是现在,当我尝试反序列化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
在这两种情况下,ClassA
和ClassB
仍然不调用ResolveName
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
我尝试使用从IDataContractSurrogate
派生的类,并在函数GetDataContractType
中转换类型,而该函数不适用于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
更新#2: 最后,我没有找到任何方法去做我想做的事。我需要查看文件版本,并在序列化之前用XML中的新标记替换旧标记。例:
data = data.Replace("<ClassA>", "<ClassBase>")
...
data=data.Replace(“,”)
...
这不是对我第一个问题的回答,而是一个解决办法
但是现在,当我尝试反序列化XML时,集合ListOfA
是
已创建但始终为空!我在反序列化过程中没有出错
在中,您可以找到有关为什么列表a
为空的信息。调整版本的反序列化引擎无法解释ClassA
或ClassB
,因此会丢弃此数据
我认为你使用的是正确的跟踪
数据协定解析器允许您配置已知类型
动态地序列化或
反序列化数据协定不需要的类型
由于未在的已知数据类型参数中指定ClassA
和ClassB
,因此不会为它们调用ResolveName()
。有关已知数据类型的详细信息。这意味着为了正确地反序列化这些旧类,您仍然需要包含它们以实现向后兼容性
但是现在,当我尝试反序列化XML时,集合ListOfA
是
已创建但始终为空!我在反序列化过程中没有出错
在中,您可以找到有关为什么列表a
为空的信息。调整版本的反序列化引擎无法解释ClassA
或ClassB
,因此会丢弃此数据
我认为你使用的是正确的跟踪
数据协定解析器允许您配置已知类型
动态地序列化或
反序列化数据协定不需要的类型
由于未在的已知数据类型参数中指定
ClassA
和ClassB
,因此不会为它们调用ResolveName()
。有关已知数据类型的详细信息。这意味着为了正确地反序列化这些旧类,您仍然需要包含它们以实现向后兼容性。上的msdn页可能对您有用。上的msdn页可能对您有用。我理解为什么我的列表为空。谢谢是的,我正在反序列化。ResolveName()是对其他类型的调用,但不是对ClassA或ClassB的调用。我编辑了我的帖子来澄清这一点。@Kipotlov我担心你将不得不保留ClassA
和ClassB
声明。查看我的更新答案。我试图将ClassA
和ClassB
作为已知数据类型放入DataContractSerializer
构造函数中,我在ClassBaseCollection
上尝试了KnownTypeAttribute
,但是ResolveName
仍然没有被ClassA
和ClassB
调用。…@Kipotlov您是否将它们放在与以前完全相同的命名空间/程序集中?尝试序列化它们,并查看新引入的类型是否与您尝试反序列化的数据相比较。(例如,在文本编辑器中打开序列化数据)@Kipotlov在这种情况下,恐怕我没有什么想法了。:/如果你找到了解决方案,一定要回答你自己的问题!我明白为什么我的名单是空的。谢谢是的,我正在反序列化。ResolveName()是对其他类型的调用,但不是对ClassA或ClassB的调用。我编辑了我的帖子来澄清这一点。@Kipotlov我担心你将不得不保留ClassA
和ClassB
声明。查看我的更新答案。我试图将ClassA
和ClassB
作为已知数据类型放入DataContractSerializer
构造函数中,我在ClassBaseCollection
上尝试了KnownTypeAttribute
,但是ResolveName
仍然没有被ClassA
和ClassB
调用。…@Kipotlov您是否将它们放在与以前完全相同的命名空间/程序集中?尝试序列化它们,并查看新引入的类型是否与您尝试反序列化的数据相比较。(例如,在文本编辑器中打开序列化数据)@Kipotlov在这种情况下,恐怕我没有什么想法了。:/如果你找到了解决方案,一定要回答你自己的问题!