Windows Developer

Das unabhängige Magazin für Microsoft-Technologien

Zirkuläre Referenzen mit ASP.NET Web API serialisieren

Tipps und Tricks rund um .NET und Visual Studio

Zirkuläre Referenzen mit ASP.NET Web API serialisieren

Zirkuläre Referenzen mit ASP.NET Web API serialisieren

Dr. Holger Schwichtenberg (MVP) und FH-Prof. Manfred Steyer teilen in der Kolumne ".NETversum" ihr Expertenwissen rund um .NET-Tools und WPF mit.

Da sowohl XML als auch JSON prinzipiell Daten in hierarchischer Form repräsentieren, sind Fälle, in denen zwei Elemente gegenseitig aufeinander verweisen, problematisch. Diese Problemstellung wird durch die beiden Klassen im nachfolgenden Listing veranschaulicht: Die Klasse Mitarbeiter verweist auf die Klasse Abteilung, und die Klasse Abteilung verweist über die Eigenschaft Manager retour auf die Klasse Mitarbeiter. Bei einer strikten hierarchischen Sterilisierung würde sich eine Endlosschleife ergeben (Listing 1).

Listing 1
public class Mitarbeiter
{
public String Name { get; set; }
public Abteilung Abteilung { get; set; }
}
public class Abteilung
{
public String Bezeichnung { get; set; }
public Mitarbeiter Manager { get; set; }
public string Budget{ get; set; }
}

Um dieses Problem zu umgehen, müssen die verwendeten Serializer angewiesen werden, Referenzen zu verwenden, anstatt referenzierte Elemente an Ort und Stelle zu platzieren und somit ggf. zu wiederholen. Der Serializer des JsonFormatters kann über seine Eigenschaft PreserveReferencesHandling zu diesem Verhalten bewegt werden.

var jf = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
[...]
jf.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.All;

Setzt der Entwickler diese Eigenschaft auf die Option PreserveReferencesHandling.All, vergibt der Serializer jedem serialisierten Objekt eine ID, und Verweise auf diese Objekte werden unter Angabe dieser IDs modelliert. Das folgende Listing demonstriert das, indem es das Ergebnis der JSON-Serialisierung der Mitarbeiterin Susi Sorglos, die Managerin der eigenen Abteilung ist, zeigt. Dabei fällt auf, dass der Serialisierer zum Darstellen von IDs die einzelnen Objekte um eine Eigenschaft $id erweitert hat. Zum Darstellen von Verweisen hat er darüber hinaus die Eigenschaft $ref eingeführt:

{
"$id": "1",
"Name": "Susi Sorglos",
"Abteilung": {
"$id": "2",
"Bezeichnung": "Abteilung Einkauf",
"Manager": {
"$ref": "1"
}
}
}

Beim Einsatz dieser Lösung ist zu beachten, dass es sich hierbei um eine Erweiterung von Json.NET, die somit nicht von allen Kommunikationspartnern verstanden wird, handelt. Der DataContractSerializer bietet für XML-Dokumente mit zirkulären Verweisen zwei ähnliche Lösungsansätze. Zum einen kann der Entwickler bei der Definition eines Datenvertrags angeben, dass Verweise auf diesen Datenvertrag durch Angabe von IDs aufzulösen sind. Dazu legt er die Eigenschaft IsReference des Attributs DataContract auf true fest (Listing 2).

Listing 2
[DataContract(IsReference = true)]
public class Abteilung
{
[DataMember(Name="AbteilungsName", IsRequired=true)]
public String Bezeichnung { get; set; }

[DataMember]
public Mitarbeiter Manager { get; set; }

[JsonIgnore]
[XmlIgnore]
public string Budget{ get; set; }
}

[DataContract(IsReference = true)]
public class Abteilung
{
[DataMember]
public String Bezeichnung { get; set; }

[DataMember]
public Mitarbeiter Manager { get; set; }
}

Alternativ dazu kann der Entwickler pro Datenvertrag in der globalen Konfiguration einen vorkonfigurierten DataContractSerializer hinterlegen. Damit diese Serializer zum Auflösen von Verweisen ID-Referenzen einsetzen, legt übergibt er den Wert true für den Parameter preserveObjectReferences deren Konstruktoren (Listing 3).

Listing 3
var dcsAbteilung = new DataContractSerializer(typeof(Abteilung), null, 
int.MaxValue, false,
/* preserveObjectReferences: */ true, null);
xf.SetSerializer<Abteilung>(dcsAbteilung);

var dcsMitarbeiter = new DataContractSerializer(typeof(Mitarbeiter), null,
int.MaxValue, false,
/* preserveObjectReferences: */ true, null);
xf.SetSerializer<Mitarbeiter>(dcsMitarbeiter);

Mehr aus dieser Ausgabe

Artikel erschienen in

Windows Developer 2.2013
Service Kommunikation
Mit den Azure Mobile Services stellt Microsoft eine Reihe von Diensten…
Der Weg in eine Public Cloud kann schon mal etwas holprig ablaufen. Manchmal…
Das jüngste Mitglied der ASP.NET-Familie, SignalR, erlaubt die Umsetzung…
Teil 1 dieser Artikelserie vermittelte die Grundlagen der asynchronen…
In der Phase der Konzeption müssen wichtige Entscheidungen hinsichtlich des…
Software-Entwicklung ist durch die hohe Verbreitung von verschiedensten…
Teil 1 dieser Artikelserie vermittelte die Grundlagen der asynchronen…
WCF Data Services: serverseitiges Paging
Dr. Holger Schwichtenberg (MVP) und FH-Prof. Manfred Steyer teilen in der…
Bereits im ersten Teil dieses Beitrags in der letzten Ausgabe zeigten wir…
Jeder wird mir beipflichten, dass sich heutige Websites von Haus aus…
WPF: Windows-8-Style für WPF
In der neuen Kolumne "XAML Expertise" des Windows Developer präsentiert Gregor…
Softwareentwicklung ist durch die hohe Verbreitung von verschiedensten…
Zirkuläre Referenzen mit ASP.NET Web API serialisieren
Dr. Holger Schwichtenberg (MVP) und FH-Prof. Manfred Steyer teilen in der…
Windows Phone 8: Neues Speech-API mit Text-to-Speech
In der neuen Kolumne "XAML Expertise" des Windows Developer präsentiert Gregor…
Windows Phone 8: Neues Speech-API mit Text-to-Speech
In der neuen Kolumne "XAML Expertise" des Windows Developer präsentiert Gregor…
Für den Endanwender haben Hintergrundprozesse oft einen unangenehmen…
Werkzeuge wie PostSharp erlauben es, nach dem eigentlichen Kompilieren…
Einführung in ASP.NET SignalR
Das jüngste Mitglied der ASP.NET-Familie, SignalR, erlaubt die Umsetzung von…
Sowohl bei Windows Phone 7 als auch bei WinRT-Applikationen für Windows 8…
Mit Retrospektiven die Arbeitsleistung steigern
Durch Retrospektiven erkennen Teams Projekthindernisse bzw. Fehlverhalten. Die…
 

Kommentare

Ihr Kommentar zum Thema

Als Gast kommentieren:

Gastkommentare werden nach redaktioneller Prüfung freigegeben (bitte Policy beachten).

WEITERE TEILE DER SERIE: dotNETversum