具有复杂类型的数据协定序列化

时间:2012-11-13 15:41:56

标签: c# .net serialization datacontractserializer

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

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

2 个答案:

答案 0 :(得分:3)

通过将数据类装饰为DataContract,您可以固有地设置数据将被表示为序列化时的结构(Xml,Json等)。

我是否可以建议您将“业务实体”和“序列化实体”的问题从数据类中分离出来,例如:如果Foo + Bar是您的内存或数据的ORM表示,请从中删除[DataContract]

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可以为你做很多工作

e.g。

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.

答案 1 :(得分: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设计进行结构化。