Как можно управлять сериализацией .NET DataContract, чтобы вместо элементов использовались атрибуты XML?

StackOverflow https://stackoverflow.com/questions/591907

Вопрос

Если у меня есть класс, отмеченный как 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 но я надеюсь, что есть более простое решение.

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

Это было полезно?

Решение

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

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

Другие советы

Вы можете сделать это с помощью DataContractSerializer - ответ взять на себя сериализацию Xml себя, реализуя IXmlSerializable интерфейс.Для write-only support - вы можете оставить реализация 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.

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

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

    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();
    }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top