2009-02-26 5 views
14

Wenn ich eine Klasse markiert habe als eine DataContract und einige Eigenschaften auf sich mit DataMember Attributen markierten ich es aus, um XML leicht serialisieren kann, aber es wäre eine Ausgabe wie zu schaffen:Wie können Sie .NET DataContract-Serialisierung steuern, sodass XML-Attribute anstelle von Elementen verwendet werden?

<Person> 
    <Name>John Smith</Name> 
    <Email>[email protected]</Email> 
    <Phone>123-123-1234</Phone> 
</Person> 

Was ich bevorzugen würde, ist Attribut wie ...

<Person Name="John Smith" Email="[email protected]" Phone="123-123-1234" /> 

Das DataMember Attribut ermöglicht es mir, den Namen und die Bestellung zu kontrollieren, aber nicht, ob es als ein Element oder Attribut serialisiert wird. Ich habe mich umgesehen und DataContractFormat und IXmlSerializable gefunden, aber ich hoffe, dass es dort eine einfachere Lösung gibt.

Was ist der einfachste Weg, dies zu tun?

+0

Auch ich brauche das XML auf diese Weise arbeiten, während JSON weiter funktioniert. – Brennan

Antwort

11

Sie können dies nicht mit der DataContractSerializer; Wenn Sie Attribute möchten, müssen Sie stattdessen die XmlSerializer verwenden. Mit der Klasse DataContractSerializer ist eine restriktivere Teilmenge der XML-Spezifikation zulässig, die die Leistung verbessert und die Interoperabilität veröffentlichter Services verbessert, Ihnen jedoch weniger Kontrolle über das XML-Format gibt.

Wenn Sie WCF-Dienste verwenden, sehen Sie sich XmlSerializerFormatAttribute an, mit dem Sie die XmlSerializer für die Serialisierung verwenden können.

+1

Es muss eine einfache Möglichkeit geben, Attribute zu verwenden. Ich interessiere mich nicht für Webdienste, sondern nur für die Ausgabe von XML in einem bestimmten Format. – Brennan

+0

Hallo, Ich ', Angst Greg ist richtig - siehe http://msdn.microsoft.com/en-us/library/ms731923.aspx für die Einschränkungen des DataContractSerializer. – larsw

+1

Wenn Sie sich nicht für Webdienste interessieren, warum verwenden Sie WCF? Versuchen Sie nur, einige Klassen zu serialisieren? Wenn ja, dann verwende den XmlSerializer selbst. –

34

Sie können dies mit dem DataContractSerializer - die Antwort ist über die XML-Serialisierung sich die IXmlSerializable Schnittstelle durch die Implementierung zu nehmen. Für Nur-Schreib-Unterstützung - können Sie die Implementierung von ReadXml leer, und return null für GetSchema, verlassen und dann schreiben die Umsetzung von WriteXml wie folgt:

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

Wenn Sie das gleiche verwenden Geben Sie beispielsweise JSON-Serialisierung ein, und Sie können dann weiterhin die Attribute DataContract und DataMember hinzufügen. Der DataContractSerializer verwendet die IXmlSerializable-Schnittstellenimplementierung nur beim Schreiben von Xml.

Ich bloggte über diese here.

+0

Sind Sie sicher, dass der 'DataContractSerializer' die' WriteXml' Methode dieses Codes aufruft? –

+1

Ich weiß - es scheint unwahrscheinlich - aber ich habe gerade einen Artikel in unserem Corporate Blog unter http: //www.labs.jobserve veröffentlicht.com/Articles.aspx/Building-Labs - Schreiben-eine-OpenSearch-Vorschläge-Anbieter-in-C-mit-WCF, wo Sie Quellcode herunterladen können, die es in Aktion zeigt (damit es OpenSearch-Vorschläge zu implementieren). Der Hinweis kam von diesem MSDN-Inhalt: http://msdn.microsoft.com/en-us/library/ms731923.aspx. –

+0

Stellen Sie sicher, dass http://msdn.microsoft.com/en-us/library/aa347876.aspx angezeigt wird. –

0

Sie können beim Serialisieren/Deserialisieren zwischen Attributen und Elementen hin- und herwechseln. Folgendes funktioniert für Letzteres.

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