I am using Data Contract serialization to serialize the following classes in 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; }
}
When I serialize it it generates XML like this:
<Foo>
<MyString>My text</MyString>
<MyInt>2</MyInt>
<MyBar>
<BarField>My bar field</BarField>
</MyBar>
</Foo>
What I would like to do is have the MyBar
field not appear as a complex type, but like this instead:
<Foo>
<MyString>My text</MyString>
<MyInt>2</MyInt>
<MyBar>My bar field</MyBar>
</Foo>
I'm new to data contract serialization and haven't found any kind of tutorials that address my issue. I don't even know if it is possible or not but I figured I'd ask before I gave up and dealt with it the way it is or found a better solution.
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.