【问题标题】:Having DataContractSerializer serialize the same class in two different ways?让 DataContractSerializer 以两种不同的方式序列化同一个类?
【发布时间】:2009-05-07 08:23:17
【问题描述】:

我正在使用 DataContractSerializer 将标有 DataMember 属性的对象属性和字段序列化为 xml。

现在同一个类有另一个用例,我需要序列化其他属性和其他字段。

有没有办法添加可用于我的其他序列化场景的“另一个 DataMemberAttribute”?

【问题讨论】:

  • 可以说,如果你需要序列化不同的属性和字段,那它实际上不是同一个类。
  • 我不同意。如果同一个类实现多个接口,某些数据元素可能只与其中一个接口相关。
  • 接口是一组行为。被序列化的是状态。如果你有两组状态,那么你就有两个类。
  • @John Saunders:是的,我跟着你,但它是相同的状态被序列化了两次,但具有两个不同的“安全级别”,因此在某些用例中限制了消费者使用某些数据.更具体地说,这是一个业务对象,在某些情况下需要使用它对其他业务对象的引用进行序列化,而在其他情况下则不需要。
  • 您是否考虑过教您的对象了解安全级别?这样,当您读取间隙不足的属性时,对象可能会返回 null/0/empty 值。

标签: c# .net wcf


【解决方案1】:

基本上没有。

如果您想使用现有的DataContractSerializer,则必须维护 DTO 类的第二个版本并在它们之间转换数据。

如果您正在编写自己的序列化代码的选项:

  • 声明您自己的[DataMember]-style 属性并在运行时在您自己的序列化代码中解释它们
  • 使用“伙伴班”
  • 使用外部元数据(例如文件)
  • 使用基于代码的配置(即通过 DSL)

实际上,我希望第一个将是最简单的选择。

【讨论】:

  • 感谢您的回复!编写我自己的序列化代码可能是一种选择,但我真的不知道从哪里开始 - 我正在使用 DataContractSurrogate 并保留引用,而且似乎需要一些努力来“模拟” DataContractSerializer 的行为。有没有办法根据现有的 DataContractSerializer 编写一个,或者是否有指向您知道的类似解决方案的链接?
  • 一整套内置的序列化技术就是这样一个笑话。他们看起来就像在做你想做的事,直到你尝试对他们做一些有用的事情。我实际上更喜欢 XAML 序列化格式,因为至少它确实伪装成其他基于 XML 的对象图格式。
  • @Darrel Miller:感谢您提供指向 XAML 序列化格式的指针。我会检查一下。
【解决方案2】:

在过去的类似场景中,我们采用了面向对象的方法,并创建了一个从主类扩展的新类。 为了帮助您使用 DataContractSerializer 实现继承,请查看 KnownTypeAttribute

在你的一个问题中,

如果同一个类实现多个接口,某些数据元素可能只与其中一个接口相关。

如果您的场景是这种情况,那么您的数据服务合同可能应该只公开接口,而不是类?

例如,如果你有这样的类:

[DataContract]
public class DataObject : IRed, IBlue

那么,您有两个操作合同,一个用于 IRed,一个用于 IBlue,而不是让您的操作合同公开 DataObject。 这消除了对自定义序列化代码的需要。

【讨论】:

  • 我认为你对最后一点非常正确。唯一的缺点是接口中会有很多重复的属性“声明”,因为大多数属性在这两种情况下都是序列化的。
  • 嗯,重复声明没什么大不了的……在我看来,它与重复的代码逻辑不同。
  • 我同意!但是让它们保持同步有点乏味......但是编译器当然会在那里帮助我,我不应该那么懒惰:)
【解决方案3】:

有办法做到这一点,但它是一个丑陋的黑客。

DataContractSerializer 可以序列化实现IXmlSerializable 接口的对象。您可以实现该接口并创建自己的ReadXml(XmlReader reader)WriteXml(XmlWriter writer) 方法,这些方法可以以不同的方式序列化对象。

请注意,您必须在类本身中嵌入一个标志,以确定序列化对象的方式。 (没有办法告诉DataContractSerializer 使用哪种模式,所以标志必须包含在对象本身中。)

正如@Marc 所建议的,第二个版本的 DTO 类会更简洁。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-25
    • 1970-01-01
    • 1970-01-01
    • 2020-07-17
    • 1970-01-01
    • 2019-12-10
    • 2015-01-05
    相关资源
    最近更新 更多