Der Dotnet-Doktor 04.05.11
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."
Dr. Holger Schwichtenberg ist selbstständiger Technologieberater, Softwarearchitekt, Dozent und Fachjournalist mit dem Schwerpunkt "Softwareentwicklung auf der Windows-Plattform".