2011-08-21 18 views
6

Czy można uzyskać ServiceStack JsonSerializer, aby przekształcić ExpandoObject jako obiekt płaski zamiast słownika? Coś mniej więcej w przybliżeniu do tego:Jak serializować ExpandoObject za pomocą ServiceStack JsonSerializer?

{"x":"xvalue","y":"\/Date(1313966045485)\/"} 

Próbuję porównać JSON serializacji ExpandoObject stosując trzy różne systemy: .NET BCL JavaScriptSerializer, Newtonsoft Json.NET i JSON oferujące ServiceStack użytkownika.

Zacznę od dość prostego obiektu dynamicznego.

dynamic test = new ExpandoObject(); 
test.x = "xvalue"; 
test.y = DateTime.Now; 

Wydaje się prostsze dla serializatora do leczenia ExpandoObject jako IDictionary<string, object>. Zarówno BCL, jak i ServiceStack zaczynają się w ten sposób, choć przechodzą dość różne trasy z wynikiem.

JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer(); 
Console.WriteLine(javaScriptSerializer.Serialize(test)); 
// [{"Key":"x","Value":"xvalue"},{"Key":"y","Value":"\/Date(1313966045485)\/"}] 

Console.WriteLine(ServiceStack.Text.JsonSerializer.SerializeToString(test)); 
// ["[x, xvalue]","[y, 8/21/2011 16:59:34 PM]"] 

wolałbym mieć ExpandoObject odcinkach bardziej jak to jest montowane w kodzie, jak typowa klasa będzie w odcinkach. Możesz add an override JavaScript serializer to the BCL system for IDictionary<string, object>. Działa to świetnie, zakładając, że nie ma tak naprawdę IDictionary<string, object>, który musi pozostać w ten sposób (czego jeszcze nie mam).

JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer(); 
javaScriptSerializer.RegisterConverters(new JavaScriptConverter[] { new ExpandoJsonConverter() }); 
Console.WriteLine(javaScriptSerializer.Serialize(test)); 
// {"x":"xvalue","y":"\/Date(1313966045485)\/"} 

Niestety, wciąż potrzebujemy sposobu na zdobycie ServiceStack za JsonSerializer do leczenia ExpandoObject w ten sam sposób. Jak podłączyć się do systemu ServiceStack, aby było to możliwe?

Aktualizacja: Chociaż nie jest to opcja do moich zastosowań, wygląda na to, że ServiceStack obsługuje anonimowe obiekty.

Console.WriteLine(ServiceStack.Text.JsonSerializer.SerializeToString(new { x = "xvalue", y = DateTime.Now })); 
// {"x":"xvalue","y":"\/Date(1313980029620+0000)\/"} 

Odpowiedz

1

Nie ma żadnych dostępnych w ServiceStack za JsonSerializer haczyki, które można podłączyć do zmiany tego zachowania, ale jestem bardziej niż zadowolony z żądania ściągania że robi to;)

Klasy trzeba będzie zmienić to:

  • JsWriter.cs (linia 223) - wstawić kod do wykrywania obiektu expando i powrotu delegata, który pisze obiekt expando jak chcesz.
  • JsReader (linia 42) - wstawić kod, aby wykryć obiekt expando i powrócić delegata do odczytania zawartości sznurku i deserializować go z powrotem do EXPANDO

Wyobrażam kod do czynienia z obiektem EXPANDO jest podobny do słownika, więc powinieneś być w stanie korzystać ze słownika klasy implementacji, aby poprowadzić Cię (tj WriteDictionary.cs i DeserializeDictionary.cs)

Zapraszamy do korzystania z forum ServiceStack jeśli masz jakieś pytania/zagadnienia na tym: https://groups.google.com/forum/#!forum/servicestack

+0

Jeśli mogę zmusić MonoTouch do użycia ServiceStack do deserializacji JSON wygenerowanego z jednego z innych systemów, ten konkretny problem nie zaszkodzi mi zbyt mocno. Nawet jeśli uda mi się go obejść, postaram się zobaczyć, co mogę zrobić, aby skomponować kod dla żądania ściągnięcia; Byłoby miło użyć ServiceStack na obu końcach mojego obecnego projektu. – patridge

+1

Oczywiście, aby ServiceStack pracował z MonoTouch, wystarczy użyć kompilacji MonoTouch dostępnej na: https: // github.com/ServiceStack/ServiceStack/drzewo/master/release/latest/MonoTouch – mythz

+0

To było łatwe. Zrobiłem to i uruchomiłem za kilka minut. Byłoby kilka sekund, gdybym nie był zrewolucjonizowany skróty klawiaturowe w MonoDevelop, jak poszedłem. – patridge

Powiązane problemy