代码之家  ›  专栏  ›  技术社区  ›  asgerhallas

让DataContractSerializer以两种不同的方式序列化同一个类?

  •  2
  • asgerhallas  · 技术社区  · 15 年前

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

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

    有没有方法添加“另一个datamemberattribute”以用于我的其他序列化方案?

    3 回复  |  直到 15 年前
        1
  •  2
  •   Marc Gravell    15 年前

    不,基本上。

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

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

    • 申报你自己的 [DataMember] -样式属性并在运行时用自己的序列化代码解释它们
    • 使用“伙伴类”
    • 使用外部元数据(如文件)
    • 使用基于代码的配置(即通过DSL)

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

        2
  •  1
  •   Scott Ferguson    15 年前

    在过去类似的场景中,我们采用了面向对象的方法,并创建了一个从主类扩展而来的新类。 要帮助您使用DataContractSerializer实现固有特性,请签出 KnownTypeAttribute

    在你对你的问题的评论中,

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

    如果在您的场景中是这样,那么您的数据服务契约应该只公开接口,而不公开类?

    例如,如果您有类似的类:

    [DataContract]
    public class DataObject : IRed, IBlue
    

    然后,您有两个操作契约,一个用于IRED,一个用于IBlue,而不是让您的操作契约公开数据对象。 这样就不需要自定义序列化代码。

        3
  •  0
  •   dthrasher    15 年前

    有办法,但这是一个丑陋的黑客。

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

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

    正如@marc所暗示的那样,DTO类的第二个版本会更干净。