Kann ich serialisieren Dictionary<string, object> mit DataContract serializer?
Ich Plane zu bauen, einen WCFservice zurückgibt, die generische dictionary-Objekte zu JSON serialisiert. Leider Serialisierung ausfällt, als Objekt ist potentiell immer anders. KnownTypes nicht helfen können, da die Eigenschaft type ist im Wörterbuch, und ich kann nicht sagen, KnownType, wie die Klasse, ist potentiell immer anders.
Irgendwelche Ideen, ob es möglich ist, zu serialisieren ein "unbekannter Typ"?
Ich kümmere mich nicht um anzugeben, DataContract/DataMember für jede meiner Klassen, aber (zumindest für die Prototyp-version) ich will nicht zu haben, die starke Typen für jeden und jede Antwort. Javascript-client kümmert sich einfach nicht.
Wie über anonyme Klassen?
- Ich bin froh, dass Leute wie dieser schon. Bitte nicht die Mühe zu Antworten, mit Argumenten wie WCF war nicht dafür gemacht, dass etc, etc. Ich würde schätzen, wenn Sie können, lassen Sie es uns wissen, wenn es einen bekannten Weg, oder wenn man einmal dort gewesen ist und gab aus triftigen Gründen (welche Gründe?).
Du musst angemeldet sein, um einen Kommentar abzugeben.
HINWEIS: ich gegangen bin, in eine Menge von details über JavaScriptSerializer am Anfang meiner Antwort, wenn Sie nur wollen, um zu Lesen über die Auflösung der bekannten Art problem erwähnt, in der ursprünglichen Frage, springen Sie an das Ende der Antwort.
Leistung
Basiert auf der benchmarks ich lief, JavaScriptSerializer ist die viel langsamer als die anderen alternativen und kann 2x so lange zum serialisieren/Deserialisieren eines Objekts im Vergleich zum DataContractSerializer.
Keine Notwendigkeit für Bekannt Geben
Sagte, die JavascriptSerializer ist mehr flexibel, da es nicht erforderlich, dass Sie angeben, "bekannte Typen" der Zeit Voraus, und die serialisierten JSON-Reiniger ist zumindest im Fall der Wörterbücher (siehe Beispiele hier).
Die Kehrseite ist, dass die Flexibilität rund bekannten Arten ist, dass Sie nicht in der Lage zu Deserialisieren, die gleichen JSON-string zurück an den ursprünglichen Typ. Zum Beispiel, angenommen ich habe eine einfache
Person
Klasse:Und wenn ich erstellen Sie eine Instanz der
Dictinoary<string, object>
und fügen Sie eine Instanz desPerson
Klasse, um es vor dem serialisieren es:Hol ich folgenden JSON
{"me":{"Name":"Yan","Age":30}}
ist sehr sauber, aber ohne jede Art von Informationen. So soll, wenn Sie zwei Klassen mit dem gleichen Mitglied Definitionen oder wennPerson
als Unterklasse definiert werden, ohne dass zusätzliche Mitglieder:dann gibt es einfach keine Möglichkeit für den serializer in der Lage sein zu garantieren, dass die JSON -
{"Name":"Yan","Age":30}
können deserialisiert werden, um den richtigen Typ.Wenn Sie Deserialisieren
{"me":{"Name":"Yan","Age":30}}
mithilfe der JavaScriptSerializer in dem Wörterbuch, das Sie wieder den Wert im Zusammenhang mit "mich" ist NICHT eine Instanz vonPerson
aber einDictionary<string, object>
stattdessen eine einfache Eigenschaft Tasche.Wenn Sie wollen zu bekommen eine
Person
Instanz zurück, könnten Sie (obwohl Sie wahrscheinlich würde Sie nie wollen!) konvertieren, dassDictionary<string, object>
mit derConvertToType
Helfer-Methode:Auf der anderen Seite, wenn Sie nicht brauchen, um über sorgen zu Deserialisieren diese JSON-in der richtigen Art und JSON serailization ist kein performance-Engpass (Profil code und finden Sie heraus, wie viel CPU-Zeit verbracht und bei der Serialisierung, wenn Sie es nicht bereits getan haben), dann würde ich sagen, nutzen Sie einfach JavaScriptSerializer.
Injektion Bekannt Geben
WENN am Ende des Tages, Sie noch müssen, zu verwenden DataContractSerializer und injizieren müssen diese KnownTypes, hier sind zwei Dinge, die Sie ausprobieren können.
1) Übergeben Sie den array mit der bekannten Typen an den DataContractSerializer Konstruktor.
2) führen Sie eine Unterklasse von DataContractResolver (mit den Mitteln zu suchen, die Typen, die für Sie von Interesse) auf der DataContractSerializer Konstruktor
Können Sie erstellen eine 'bekannte Art der Registrierung" der Sorten, verfolgt von den Typen, die Hinzugefügt werden können, um das Wörterbuch, und wenn Sie die Kontrolle aller Typen, die Sie injizieren müssen, um die DataContractSerializer, Sie können versuchen, die einfachste Sache:
Erstellen Sie eine
KnownTypeRegister
Klasse mit statischen Methoden zum hinzufügen eines Typs zu der Liste der bekannten Typen:Fügen Sie einen statischen Konstruktor registriert den Typen mit der register:
Holen Sie sich die Reihe von bekannten Arten, die aus dem register, wenn Sie konstruieren die serializer:
var serializer = new DataContractSerializer(typeof(Dictionary<string, object>), KnownTypeRegister.Get());
Dynamischer/besser Optionen sind möglich, aber Sie sind auch schwieriger zu implementieren, wenn Sie möchten Lesen Sie mehr über dynamic bekannte Art Auflösung, einen Blick auf Juval LÖWY MSDN Artikel zu dem Thema hier.
Auch, in diesem blog-post von Carlos Figueira geht auch in details auf fortgeschrittene Techniken wie dynamisch die Generierung der Typen, sowie der Wert, gelesen zu werden, während Sie auf das Thema!
Haftungsausschluss ich nicht empfehlen, Sie setzen
object
auf einem WCF-Endpunkt; obwohl dies scheint 'flexibel' das ist keine gute Idee, da Sie nicht angegeben haben, welche Art von Informationen serviert werden, die von Ihrem service.und jetzt für eine Antwort
Wenn Sie Ihre WCF-Aufruf verbraucht wird durch einen ajax-Aufruf und wie Sie es
Javascript client just doesn't care.
dann warum nicht machen Sie Ihre WCF-Aufruf einfach einen string zurückgeben? Dann das innere Ihrer WCF-Aufruf serialisiert dieDictionary<string, object>
mithilfe der JavaScriptSerializerdisclaimer2 Dies ist ein Mittel zum Zweck (da Sie die Frage gestellt hat) - Für eine Qualität in der Produktion Anwendung hätte ich eine gut definierte Schnittstelle, also war es klar, was angefordert wurde und zurück geschickt über den Draht.
DataContract
wäre schneller. Aber es würde mich Wundern, wenn serialisieren mithilfe einer Dritten Partei JSON serializer (eg Json.NET) und die Rückgabe einer Zeichenfolge schneller sein könnte als erste WCF serialisiert. Und Nein, die strenge Typisierung wird nicht helfen, mit der javascript-Seite der Dinge, sondern mit der strikten Typisierung Sie können sich Ihre "öffentlichen API' und sehen genau, was Sie setzen, im Gegensatz zum herausstellen einesDictionary<string, object>
gibt wer weiß was.