没有 xsi:type 的 DataContractResolver

Posted

技术标签:

【中文标题】没有 xsi:type 的 DataContractResolver【英文标题】:DataContractResolver without a xsi:type 【发布时间】:2021-11-01 19:04:34 【问题描述】:

为了兼容性,我需要将旧的 DataContract-XML 反序列化为具有抽象类型的新模型。

旧模型和旧 XML

[DataContract]
class OldType 
  [DataMember] public string Hello;


List<OldType> serializeMe = new List<~>() new OldType(); 
serializer.WriteObject(..., serializeMe);
<OldType>
  <Hello></Hello>
</OldType>

新模型和 XML

[DataContract]
abstract class AbstractType 
 [DataMember] public string Hello;


[DataContract]
class NewType : AbstractType 
  // only non serialized fields


List<AbstractType> serializeMe = new List<~>() new NewType(); 
serializer.WriteObject(..., serializeMe);
<AbstractType i:type="b:NewType" mlns:b="..Namespace">
  <Hello></Hello>
</AbstractType>

现在这显然不能那样工作。我希望使用DataContractResolver 将旧类型映射到新的抽象类型。但是,解析器仅对使用 xsi:type 声明的节点调用。 我能想到的最后一种可能性是使用 string.replace,但这很丑陋。还有什么建议吗?或者我可以将DataContractResolver 更改为总是被调用吗?

【问题讨论】:

类型用于继承类。所以原始代码只有一个没有继承类的基类。新代码具有继承的类。所以你只需要添加继承的类。确保使用 XmlInclude。请参阅:docs.microsoft.com/en-us/dotnet/api/… 暂时搁置xsi:type 问题,您将进行更基本的更改:您将data contract name 从&lt;OldType&gt; 更改为&lt;AbstractType&gt;。正如the docs 和How to change the Type of DataContract property without breaking backwards compatibility? 中所解释的那样,总是会崩溃 引用this answer 由TheGeneral 到How to change the Type of DataContract property without breaking backwards compatibility?。 你不能这样做,这违反了合同......你需要以某种方式削减和运行。您可能需要进行管道处理以处理较旧的合同。 您能否解释一下为什么要使用序列化程序级别而不是更高级别来解决这个问题? @jdweng - 问题是关于DataContractSerializer,您的评论适用于XmlSerializer @dbc 是的,完全正确。我决定放弃这种方法,而不是将我的模型更改为数据,我只是添加了一个额外的映射 DTO 并将名称和命名空间映射到旧的。好多了,我不明白我为什么不考虑这个。 【参考方案1】:

感谢@dbc 我找到了正确的解决方案。 我没有将模型更改为数据,而是添加了一个额外的映射 DTO,并将名称和命名空间映射到旧的。好多了。

[DataContract(Name="OldType")]
class DataContractOldType 
  [DataMember] public string Hello;

  AbstractType MapToCorrectType()  .... 

【讨论】:

以上是关于没有 xsi:type 的 DataContractResolver的主要内容,如果未能解决你的问题,请参考以下文章

如何使用XSLT映射删除xsi:type =“xsd:string”&xsi:nil =“true”?

如何定位命名空间 xsi:type="test1"

无法在路径中使用 <xsi:type=> 设置 SQL XML 节点级别

从 xml/json JAXB 中删除 xsi:type 信息?

XmlSchemaValidationException:这是一个无效的 xsi:type 'Book' 尝试反序列化使用 XSD 架构验证它的 XML 时

如何使用 JAXB 创建没有价值的 XmlElement