1

我正在使用数据协定序列化来序列化 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>

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

4

2 回答 2

3

通过将数据类装饰为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.
于 2012-11-13T15:55:45.497 回答
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; }
}

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

于 2012-11-13T15:45:41.160 回答