【问题标题】:Data contract serialization with complex types具有复杂类型的数据合约序列化
【发布时间】:2012-11-02 01:30:18
【问题描述】:

我正在使用 Data Contract 序列化来序列化 XML 中的以下类:

[DataContract]
public partial class Foo
{
    [DataMember]
    public string MyString { get; set; }
    [DataMember]
    public int MyInt { get; set; }
    [DataMember]
    public Bar MyBar { get; set; }
}

[DataContract]
public class Bar
{
    public int BarId { get; set; }
    [DataMember]
    public string BarField { get; set; }
}

当我序列化它时,它会生成这样的 XML:

<Foo>
    <MyString>My text</MyString>
    <MyInt>2</MyInt>
    <MyBar>
        <BarField>My bar field</BarField>
    </MyBar>
</Foo>

我想做的是让MyBar 字段不显示为复杂类型,而是像这样:

<Foo>
    <MyString>My text</MyString>
    <MyInt>2</MyInt>
    <MyBar>My bar field</MyBar>
</Foo>

我是数据合约序列化的新手,还没有找到任何类型的教程来解决我的问题。我什至不知道这是否可能,但我想在我放弃之前我会问一下,并按照它的方式处理它或找到更好的解决方案。

【问题讨论】:

    标签: c# .net serialization datacontractserializer


    【解决方案1】:

    通过将数据类装饰为DataContract,您本质上设置了数据在序列化时将表示的结构(Xml、Json 等)。

    我能否建议您将“业务实体”和“序列化实体”的关注点从您的数据类中分离出来,例如如果 Foo + Bar 是您在内存中或数据的 ORM 表示,则从中删除 [DataContract]s:

    public partial class Foo
    {
        public string MyString { get; set; }
        public int MyInt { get; set; }
        public Bar MyBar { get; set; }
    }
    
    public class Bar
    {
        public string BarField { get; set; }
    }
    

    然后,提供一个专门针对序列化格式的新类,用DataContract装饰

    [DataContract]
    public partial class SerializableFoo
    {
        [DataMember]
        public string MyString { get; set; }
        [DataMember]
        public int MyInt { get; set; }
        [DataMember]
        public string MyBar { get; set; }
    }
    

    然后提供一个映射函数来从一个映射到另一个。 LINQ 非常适合这种工作,如果类的属性名称大多相同,那么 AutoMapper 可以为您完成很多工作

    例如

    var wireFoo = new SerializableFoo()
    {
        MyString = foo.MyString,
        MyInt = foo.MyInt,
        MyBar = foo.Bar.BarField // Do the projection / flattening here
    }
    // Serialize wireFoo here, or return it from a WCF Service, etc.
    

    【讨论】:

      【解决方案2】:

      您将它定义为一个复杂类型...这意味着它会这样出现。如果您不希望这样,请将 Foo 的数据协定更改为将 Bar 作为字符串,而不是复杂类型。

      基本上,在 XML 术语中,您将类定义为 DataContract,将属性定义为 DataMembers,您正在创建复杂对象或包含元素的元素。在您介绍的情况下,您将更改您的第一个数据合同,使其不包含额外的复杂对象,只包含您想要的数据。

      但是,当在这些 SOA 情况下应用 OO 设计时,根据您要完成的任务,其他复杂对象内部的复杂对象可能比充满属性的巨大复杂对象更容易处理,甚至更容易阅读.

      为了得到你的结果,你可以放弃你的 Bar 类,只在 Foo 中返回一个字符串。

      [DataContract]
      public partial class Foo
      {
          [DataMember]
          public string MyString { get; set; }
          [DataMember]
          public int MyInt { get; set; }
          [DataMember]
          public string MyBar { get; set; }
      }
      

      编辑:我想我的答案不够清楚,即 NO 你不能得到你想要的东西并保持你的复杂类型。您的 XML 将根据您的 OO 设计进行结构化。

      【讨论】:

      • 感谢您的回答,但这不是我要问的。我问是否可以在维护复杂类型的同时完成我想要的功能。如果您的解决方案是放弃复杂类型并使其成为字符串,那么您应该告诉我不。如果我的情况像我给出的例子一样简单,那会很好用。不幸的是,它不是。
      猜你喜欢
      • 1970-01-01
      • 2020-05-25
      • 1970-01-01
      • 1970-01-01
      • 2021-02-24
      • 2022-12-15
      • 1970-01-01
      • 2013-04-03
      • 1970-01-01
      相关资源
      最近更新 更多