Как вы можете контролировать сериализацию .NET DataContract, чтобы она использовала атрибуты XML вместо элементов? - PullRequest
15 голосов
/ 26 февраля 2009

Если у меня есть класс, помеченный как DataContract, и несколько свойств, помеченных с помощью атрибутов DataMember, я могу легко сериализовать его в XML, но при этом получится вывод:

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

То, что я бы предпочел, это атрибуты, как ...

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

Атрибут DataMember позволяет мне контролировать Имя и Порядок, но не определяет, сериализован ли он как элемент или атрибут. Я оглянулся и нашел DataContractFormat и IXmlSerializable, но я надеюсь, что есть более простое решение.

Какой самый простой способ сделать это?

Ответы [ 3 ]

37 голосов
/ 17 августа 2009

Вы можете сделать это с DataContractSerializer - ответ взять на себя сериализацию Xml самостоятельно путем реализации IXmlSerializable интерфейс. За поддержка только для записи - вы можете оставить реализация ReadXml пуста, и вернуть null для GetSchema, а затем написать реализацию WriteXml следующим образом:

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

Если вы используете тот же тип, например, для сериализации JSON, то вы все равно можете свободно добавлять атрибуты DataContract и DataMember - DataContractSerializer будет использовать реализацию интерфейса IXmlSerializable только при написании Xml.

Я писал об этом здесь .

13 голосов
/ 26 февраля 2009

Вы не можете сделать это с DataContractSerializer; если вы хотите атрибуты, вы должны использовать вместо XmlSerializer. С классом DataContractSerializer разрешено более ограниченное подмножество спецификации XML, которое повышает производительность и улучшает взаимодействие опубликованных сервисов, но дает вам гораздо меньший контроль над форматом XML.

Если вы используете службы WCF, взгляните на XmlSerializerFormatAttribute, который позволяет использовать XmlSerializer для сериализации.

0 голосов
/ 21 мая 2012

Вы можете конвертировать туда и обратно между атрибутами и элементами при сериализации / десериализации. Следующие работы для последнего.

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