Data contract serialization with complex types

这一生的挚爱 提交于 2019-12-07 04:58:28

By decorating data classes as DataContract, you are inherently setting the structure (Xml, Json etc) that the data will be represented as when it is serialized.

Can I suggest that you split the concerns of 'Business Entity' and 'Serialization Entity' out of your data classes, e.g. if Foo + Bar are your in memory or ORM representations of the data, then remove the [DataContract]s from them:

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; }
}

Then, provide a new class specifically for the serialized format, decorated with DataContract

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

And then provide a mapping function to map from the one to the other. LINQ is awesome for this kind of work, and if the classes have mostly the same property names, then AutoMapper can do a lot of the work for you

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.

You are defining it as a complex type... which means that it will come through as such. If you do not want that, then change your data contract for Foo to have Bar as a String, and not a complex type.

See basically, in XML terms, you define your class as a DataContract and your properties as DataMembers, you are creating your complex object, or an element that contains elements. In the case you presented, you would change your first data contract, so that it doesn't contain additional complex objects, only the data you want.

However, when applying OO design in these SOA situations, depending on what you are trying to accomplish, complex objects inside of other complex objects, can be easier to deal with, and even read, than a HUGE complex object full of properties.

To get your result, you would drop your Bar class and just have a string return in Foo.

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

EDIT: I guess I was not clear enough in the answer, which is NO you cannot get what you want and keep your complex types. Your XML is going to be structured based on your OO design.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!