.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在这种情况下,恐怕我没有什么想法了。:/如果你找到了解决方案,一定要回答你自己的问题!