WCF-Tipp: Anpassung der Serialisierung von String-Listen mit CollectionDataContractAttribute
Standardmäßig serialisiert WCF eine Zeichenkettenliste mit <string>-Tags. Wenn man hier den Tag-Namen ändern will, hilft die Annotation [CollectionDataContractAttribute].
- Dr. Holger Schwichtenberg
Einer unserer Kunden legt viel Wert darauf, dass das XML, das bei der WCF-Webservice-Kommunikation ausgetauscht wird, "hübsch" und sprechend ist. Eine der Wünsche war, dass eine Liste von Zeichenketten (List<string>
) nicht als <string>
-Tag im XML erscheinen soll, sondern entsprechend des Listennamens mit einem wählbaren Namen.
Diese C#-Klasse besitzt als Attribute eine Zeichenkette und eine Liste von Zeichenketten.
[DataContract(Namespace = "http://www.IT-Visions.de/Demo")]
public class Mitarbeiter1
{
[DataMember]
public string Name { get; set; }
[DataMember]
public List<string> Themen { get; set; }
}
Die Standardserialisierung sieht wie folgt aus:
<Mitarbeiter xmlns="http://www.IT-Visions.de/Demo"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Name>Holger Schwichtenberg</Name>
<Themen xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<a:string>.NET</a:string>
<a:string>WCF</a:string>
<a:string>Entity Framework</a:string>
<a:string>u.a.</a:string>
</Themen>
</Mitarbeiter>
Wenn das Serialisierungsergebnis aber nun so aussehen soll:
<Mitarbeiter xmlns="http://www.IT-Visions.de/Demo"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Name>Holger Schwichtenberg</Name>
<Themen>
<Thema>.NET</Thema>
<Thema>WCF</Thema>
<Thema>Entity Framework</Thema>
<Thema>u.a.</Thema>
</Themen>
</Mitarbeiter>
dann muss man die Klassendefinition anpassen. Hier gilt es dann, eine eigene Listenklasse zu erzeugen, die von List<string>
erbt und die Annotation [CollectionDataContractAttribute]
besitzt, in der man mit ItemName
definiert, wie die Elemente heißen soll. Mit Namespace hat man dann auch die Kontrolle über den XML-Namensraum.
[DataContract(Namespace = "http://www.IT-Visions.de/Demo")]
public class Mitarbeiter
{
[DataMember]
public string Name { get; set; }
[DataMember]
public Themenliste Themen { get; set; }
}
[CollectionDataContractAttribute(ItemName = "Thema", Namespace = "http://www.IT-Visions.de/Demo")]
public class Themenliste : List<string>
{
}
Leider geht es nur über eine eigene Listenklasse, denn [CollectionDataContractAttribute]
darf man nicht einfach vor die Deklaration des Attrbuts Themenliste setzen: "'CollectionDataContractAttribute' is not valid on this declaration type. It is only valid on 'class, struct' declarations."
()