If I have a class marked as a DataContract
and a few properties on it marked with DataMember
attributes I can serialize it out to XML easily, but it would create output like:
<Person>
<Name>John Smith</Name>
<Email>[email protected]</Email>
<Phone>123-123-1234</Phone>
</Person>
What I would prefer is attributes, like...
<Person Name="John Smith" Email="[email protected]" Phone="123-123-1234" />
The DataMember
attribute allows me to control the Name and Order but not whether it is serialized as an element or attribute. I have looked around and found DataContractFormat
and IXmlSerializable
but I am hoping there is there an easier solution.
What is the easiest way to do this?
You can do this with the DataContractSerializer - the answer is to take over the Xml serialization yourself by implementing the IXmlSerializable interface. For write-only support - you can leave the implementation of ReadXml empty, and return null for GetSchema, and then write the implementation of WriteXml as follows:
public class MyPerson : IXmlSerializable
{
public string Name { get; set;}
public string Email { get; set;}
public string Phone { get; set;}
public XmlSchema GetSchema() { return null; }
public void ReadXml(XmlReader reader) { }
public void WriteXml(XmlWriter writer)
{
writer.WriteAttributeString("name", Name);
writer.WriteAttributeString("email", Email);
writer.WriteAttributeString("phone", Phone);
}
}
If you're using the same type for, say, JSON serialization as well, then you are still free to add the DataContract and DataMember attributes - the DataContractSerializer will utilise the IXmlSerializable interface implementation only when writing Xml.
I blogged about this here.