Passing rekursive Sammlung durch WCF
-
26-09-2019 - |
Frage
Ich mag einen ziemlich allgemeinen Satz von Daten durch eine WCF-Methode übergeben. Die Daten sind im Grunde nur ein hierarchischer Satz von Schlüssel / Wert-Paare, aber es ist auf einen beliebigen Ebene verschachtelt. Ich ursprünglich betrachtet es aber als ein einziger String übergeben und tun XML oder JSON oder ähnliche Codierung / an beiden Enden Decodierung, aber da der WCF Transport ist XML sowieso, die ein wenig albern vorkam, so ich hoffe, es gibt einen Weg, um es passieren "natürlich".
Das Verfahren ist recht einfach:
[OperationContract]
void ProcessData(DataTree tree);
mit:
public class DataTree : Dictionary<string, DataTree>
{
}
Das alles compiliert in Ordnung, aber wenn ich versuche, den Dienst starten Sie es mit einem Stackoverflow unter DataContract.GetStableName abstürzt.
Ich habe versucht, ein [CollectionDataContract]
Attribut auf der DataTree
Klasse setzen und ausdrücklich alle die Namen angibt, aber das schien keinen Unterschied zu machen.
Ich habe auch versucht, ein [DataContract]
darauf setzen, aber dann scheitert es schon früher, weil Dictionary
ist ISerializable
.
Irgendwelche Ideen? Gibt es einen besseren Weg, dies zu tun?
Lösung 2
Wie sich herausstellte, eine weitere Anforderung kam (einen einfachen Wert für einen Knoten zusätzlich zu einer Liste von Kindern Angabe), so endete ich für sie ein Kind Typ oben definiert, wie auch immer, die WCF glücklich mit ihm gemacht zu haben scheint :
[CollectionDataContract(IsReference = true, ItemName = "Param",
KeyName = "Name", ValueName = "Data")]
public class DataTree : Dictionary<string, DataTreeEntry>
{
}
[DataContract]
public class DataTreeEntry
{
[DataMember]
public string Value { get; set; }
[DataMember]
public DataTree Children { get; set; }
}
Andere Tipps
Für große Objektbäume in der Vergangenheit habe ich die Daten selbst zu einem Byte-Array serialisiert, die mit WCF geschickt wird (und WCF nicht über SOAP / XML sein, wenn Sie WCF in beiden Enden haben), und dann deserialisiert es manuell auf dem empfangenden Ende.
erstellen Grundsätzlich einen Serialize(BinaryWriter writer)
und DeSerialize(BinaryReader reader)
für die Klassen in Frage, die mich serialisiert, und übergibt das Schreib- / Lesegerät bis zu den untergeordneten Objekten für rekursive Serialisierung.
Sie könnten auch in aussehen mit protobuf-net für die Serialisierung / Deserialisierung. Entweder als der Transport auf dem WCF-Anruf oder manuell, und Leiten einen Byte-Array über den Draht.