¿Cómo se puede controlar la serialización .NET DataContract para que use atributos XML en lugar de elementos?

Si tengo una clase marcada como DataContract y algunas propiedades marcadas con los atributos de DataMember , puedo serializarla en XML fácilmente, pero crearía resultados como:

  John Smith john.smith@acme.com 123-123-1234  

Lo que preferiría son atributos, como …

  

El atributo DataMember me permite controlar el nombre y el orden, pero no si se serializa como un elemento o atributo. He buscado y he encontrado DataContractFormat y IXmlSerializable pero espero que haya una solución más fácil.

¿Cuál es la forma más fácil de hacer esto?

No puede hacer esto con DataContractSerializer ; si quiere atributos, necesita usar el XmlSerializer en XmlSerializer lugar. Con la clase DataContractSerializer , se permite un subconjunto más restrictivo de la especificación XML que mejora el rendimiento y mejora la interoperabilidad de los servicios publicados, pero le otorga un control bastante menor sobre el formato XML.

Si está utilizando servicios WCF, eche un vistazo a XmlSerializerFormatAttribute que le permite usar el XmlSerializer para la serialización.

Puede hacer esto con DataContractSerializer; la respuesta es hacerse cargo de la serialización Xml mediante la implementación de la interfaz IXmlSerializable. Para soporte de solo escritura: puede dejar la implementación de ReadXml vacía y devolver nulo para GetSchema, y ​​luego escribir la implementación de WriteXml de la siguiente manera:

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

Si está utilizando el mismo tipo para, por ejemplo, serialización JSON, entonces aún puede agregar los atributos DataContract y DataMember; DataContractSerializer utilizará la implementación de la interfaz IXmlSerializable solo cuando escriba Xml.

Blogé sobre esto aquí .

Podría convertir de ida y vuelta entre atributos y elementos al serializar / deserializar. Los siguientes trabajos para este último.

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