Comment pouvez-vous contrôler la sérialisation .NET DataContract il utilise des attributs XML au lieu des éléments?
-
09-09-2019 - |
Question
Si j'ai une classe marquée comme DataContract
et quelques propriétés sur elle marqué avec les attributs DataMember
je sérialiser vers XML facilement, mais ce serait créer une sortie comme:
<Person>
<Name>John Smith</Name>
<Email>john.smith@acme.com</Email>
<Phone>123-123-1234</Phone>
</Person>
Ce que je préférerais, comme les attributs est ...
<Person Name="John Smith" Email="john.smith@acme.com" Phone="123-123-1234" />
L'attribut DataMember
me permet de contrôler le nom et l'ordre, mais pas si elle est sérialisé comme un élément ou un attribut. Je l'ai regardé et trouvé DataContractFormat
et IXmlSerializable
mais j'espère qu'il ya là une solution plus facile.
Quelle est la meilleure façon de le faire?
La solution
Vous ne pouvez pas le faire avec le DataContractSerializer
; si vous voulez attributs que vous devez utiliser le XmlSerializer
à la place. Avec la classe DataContractSerializer
un sous-ensemble plus restrictive de la spécification XML est autorisée qui améliore les performances et améliore l'interopérabilité des services publiés, mais vous donne un contrôle un peu moins sur le format XML.
Si vous utilisez des services WCF alors jetez un oeil à XmlSerializerFormatAttribute
qui vous permet d'utiliser le XmlSerializer
pour la sérialisation.
Autres conseils
Vous pouvez le faire avec le DataContractSerializer - la réponse est de prendre en charge la sérialisation Xml vous en mettant en œuvre la Interface IXmlSerializable. Pour support en écriture seule - vous pouvez laisser le la mise en œuvre de ReadXml vide, et return null pour GetSchema, puis écrire la mise en œuvre de WriteXml comme suit:
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 vous utilisez le même type, disons, sérialisation JSON aussi bien, alors vous êtes toujours libre d'ajouter les attributs DataContract et DataMember - DataContractSerializer utilisera la mise en œuvre de l'interface IXmlSerializable que lors de l'écriture Xml
.Je blogué sur ce ici .
Vous pouvez convertir dans les deux sens entre les attributs et éléments lors de la sérialisation / désérialisation. Les travaux suivants pour ce dernier.
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();
}