2011-08-21 8 views
6

È possibile ottenere che ServiceStack JsonSerializer serializzi un ExpandoObject come un oggetto piatto anziché un dizionario? Qualcosa di grosso modo approssimativo a questo:Come serializzare ExpandoObject usando ServiceStack JsonSerializer?

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

sto cercando di confrontare JSON serializzazione di ExpandoObject utilizzando tre diversi sistemi: il NET BCL JavaScriptSerializer, Newtonsoft Json.NET, e l'offerta di JSON ServiceStack.

Inizio con un oggetto dinamico abbastanza semplice.

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

Sembra semplice per un serializzatore per il trattamento di un ExpandoObject come IDictionary<string, object>. Sia BCL che ServiceStack iniziano in questo modo, anche se seguono percorsi abbastanza diversi con il risultato.

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]"] 

io preferirei avere ExpandoObject serializzato più come è assemblato in codice, come una classe tipico potrebbe essere serializzato. È possibile add an override JavaScript serializer to the BCL system for IDictionary<string, object>. Funziona alla grande, supponendo che uno non abbia in realtà un IDictionary<string, object> che deve rimanere in quel modo (cosa che non ho ancora).

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

Purtroppo, ho ancora bisogno di un modo per ottenere JsonSerializer di ServiceStack per il trattamento di un ExpandoObject nello stesso modo. Come faccio ad agganciare il sistema ServiceStack per renderlo possibile?

Aggiornamento: Sebbene non sia un'opzione per i miei usi, sembra che ServiceStack gestisca correttamente gli oggetti anonimi.

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

risposta

1

Non ci sono ganci disponibili in JsonSerializer di ServiceStack che si può collegare a modificare questo comportamento, ma io sono più che felice di prendere una richiesta di pull che lo fa;)

Le classi è necessario cambiare sono:

  • JsWriter.cs (linea 223) - inserire il codice di rilevare un oggetto expando e restituire un delegato che scrive l'oggetto expando come si desidera.
  • JsReader (Linea 42) - inserire il codice per rilevare un oggetto expando e restituire un delegato per leggere il contenuto di una stringa e deserializzare di nuovo in un expando

immagino il codice per trattare con un oggetto expando è simile ad un dizionario così si dovrebbe essere in grado di utilizzare le classi di implementazione dizionario per guidare l'utente (ad esempio WriteDictionary.cs e DeserializeDictionary.cs)

Sentitevi liberi di utilizzare il forum ServiceStack se avete altre domande/i problemi su questo: https://groups.google.com/forum/#!forum/servicestack

+0

Se riesco a far utilizzare a MonoTouch ServiceStack per deserializzare JSON generato da uno degli altri sistemi, questo specifico problema non mi farà veramente molto male. Anche se riuscirò a risolverlo, cercherò di vedere cosa posso fare per mettere insieme del codice per una richiesta di pull; sarebbe bello usare ServiceStack su entrambe le estremità del mio attuale progetto. – patridge

+1

Certo, per far funzionare ServiceStack su MonoTouch è sufficiente usare il build MonoTouch che è disponibile su: https: // github.it/ServiceStack/ServiceStack/tree/master/release/latest/MonoTouch – mythz

+0

È stato facile. L'ho installato e funzionante in pochi minuti. Sarebbero stati secondi se non avessi riacquistato le scorciatoie da tastiera in MonoDevelop mentre andavo. – patridge