WCF-Tipp: Anpassung der Serialisierung von String-Listen mit CollectionDataContractAttribute

Der Dotnet-Doktor  –  1 Kommentare

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."