Как вы можете контролировать сериализацию .NET DataContract, чтобы вместо XML использовать атрибуты XML?
Если у меня есть класс, помеченный как DataContract
, и несколько свойств на нем, помеченные атрибутами DataMember
, я могу легко его сериализовать в XML, но он создавал бы вывод, например:
<Person>
<Name>John Smith</Name>
<Email>[email protected]</Email>
<Phone>123-123-1234</Phone>
</Person>
Что бы я хотел, это атрибуты, например...
<Person Name="John Smith" Email="[email protected]" Phone="123-123-1234" />
Атрибут DataMember
позволяет мне управлять именем и порядком, но не быть сериализован как элемент или атрибут. Я огляделся и нашел DataContractFormat
и IXmlSerializable
, но я надеюсь, что там есть более легкое решение.
Каков самый простой способ сделать это?
Ответы
Ответ 1
Вы не можете сделать это с помощью DataContractSerializer
; если вам нужны атрибуты, вам нужно использовать XmlSerializer
. С классом DataContractSerializer
разрешено более ограничительное подмножество спецификации XML, что повышает производительность и улучшает совместимость опубликованных служб, но дает вам более ограниченный контроль над XML-форматом.
Если вы используете службы WCF, посмотрите XmlSerializerFormatAttribute
, что позволяет использовать XmlSerializer
для сериализации.
Ответ 2
Вы можете сделать это с помощью
DataContractSerializer - ответ
взять на себя сериализацию Xml
самостоятельно,
IXmlSerializable интерфейс. Для
поддержка только для записи - вы можете оставить
реализация ReadXml пуста и
return 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.
Я написал об этом здесь.
Ответ 3
Вы можете конвертировать назад и вперед между атрибутами и элементами при сериализации/десериализации. Следующие работы для последнего.
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();
}