How can you control the serialization of .NET DataContract to use XML attributes instead of XML?

If I have a class marked as DataContract and several properties on it marked with DataMember , I can easily serialize it to XML, but it would produce output, for example:

 <Person> <Name>John Smith</Name> <Email>john.smith@acme.com</Email> <Phone>123-123-1234</Phone> </Person> 

What I would like are attributes, for example ...

 <Person Name="John Smith" Email="john.smith@acme.com" Phone="123-123-1234" /> 

The DataMember allows me to control the name and order, but not be serialized as an element or attribute. I looked around and found DataContractFormat and IXmlSerializable , but I hope there is an easier solution there.

What is the easiest way to do this?

+14
serialization xml-serialization datacontract
Feb 26 '09 at 18:47
source share
3 answers

You cannot do this with a DataContractSerializer ; if you need attributes, you need to use XmlSerializer . With the DataContractSerializer class, a more restrictive subset of the XML specification is allowed, which improves performance and improves compatibility of published services, but gives you more limited control over the XML format.

If you use WCF services, check out the XmlSerializerFormatAttribute , which allows you to use the XmlSerializer for serialization.

+11
Feb 26 '09 at 18:50
source share

You can do this with the DataContractSerializer - the answer is to serialize the Xml yourself, IXmlSerializable interface. For write-only support, you can leave the ReadXml implementation empty and return null for GetSchema, and then write the WriteXml implementation 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 use the same type, for example, to serialize JSON, then you can still add the DataContract and DataMember attributes - DataContractSerializer will use the IXmlSerializable interface implementation only when writing Xml.

I wrote about it here .

+34
Aug 17 '09 at 11:25
source share

You can convert back and forth between attributes and elements during serialization / deserialization. The following works for the latter.

  private XmlReader AttributesToElements( Stream stream ) { var root = XElement.Load( stream ); foreach ( var element in root.Descendants() ) { foreach ( var attribute in element.Attributes() ) element.Add( new XElement( root.Name.Namespace + attribute.Name.LocalName, (string)attribute ) ); element.Attributes().Remove(); } return root.CreateReader(); } 
0
May 20, '12 at 21:35
source share



All Articles