2013-07-29 16 views
14

Quando configuro WCF per utilizzare la serializzazione jSON e includo un DataTable in uno dei miei DataContracts, serializza DataTable su XML prima di serializzare l'intero DataContract su jSON. Voglio che DataTable sia serializzato come jSON, non XML.Qual è il modo migliore per serializzare jSON un DataTable .NET in WCF?

Le mie domande sono:

  1. Perché si serializzare l'DataTable in formato XML per primo?
  2. Come posso farlo serializzare su jSON?
+0

Benvenuti in S.O. Che cosa hai provato per serializzare in json? –

+0

Considera questo e converti il ​​tuo datatable in JSON http: // stackoverflow.it/questions/17398019/how-to-convert-datatable-to-json-in-c-sharp –

risposta

13
  1. DataTable è un costrutto .NET puro che non può essere (facilmente) rappresentato in modo senza perdite da JSON. DataTable contiene molte informazioni aggiuntive che JSON non può memorizzare: chiavi primarie, autoincs, consentire null, didascalia, tipo di dati, indici, ecc. La serializzazione in XML/binario sono gli unici modi in cui un DataTable può essere serializzato in modo nativo da .NET. Questo DataTable serializzato XML viene quindi serializzato su JSON.

  2. Usa JSON.NET o FastJSON per convertire un DataTable ad una pianura, versione pulita compatibile con JSON della DataTable, che può essere consumato da qualsiasi client JSON, non solo i clienti .NET WCF. Perderai tutte le proprietà personalizzate DataTable menzionate in (1) sopra e otterrai solo la coppia JSON nome campo/valore. L'archiviazione in questo modo è inefficiente a causa della duplicazione dei nomi dei campi in ogni riga.

Non utilizzare DataTable nel DataContract. Se si desiderano i vantaggi di un DataTable e i client saranno sempre .NET, serializzare DataTable su un array di byte tramite serializzazione binaria e quindi opzionalmente comprimere il flusso di byte serializzato risultante. Esporre un array di byte nel tuo DataContract. Ciò fornirà una versione efficiente e completamente senza perdite del DataTable sul lato client (dopo la decompressione e la deserializzazione binaria), non una versione JSON annacquata di un DataTable (come offerto da (2)) ...

+0

Grandi risposte. Grazie. I miei clienti non sono tutti .NET e ho scoperto rapidamente le inefficienze che hai menzionato. Ho intenzione di provare a modificare questo approccio in modo da non dover includere i nomi di colonna/campo con ogni riga. – rhyno

+0

so che questo è un vecchio thread, ma fastjson supportava serializzazione/deserializzazione datatable dalla versione 1.7.7 che è stata rilasciata prima di giugno 2011. e il formato xml è inefficace, include tag ingombrante per ogni campo AND row. –

+0

@Keith Blows, che ne dici di serializzare un elenco di DataTable? Come suggerisci di farlo? – Xegara

2

Secondo la tabella sulla sua home page, Json.NET è davvero l'unica opzione - è possibile ottenere rapidamente da NuGet. Fortunatamente è una grande biblioteca e molto facile da usare.

string json = JsonConvert.SerializeObject(myDataSet, new DataSetConverter()); 

Nota che Rich Strahl ha un grande post con maggiori dettagli, e lui comprende anche un lavoro personalizzato che ha fatto da usare JavaScriptSerializer con (piuttosto ampie) convertitori personalizzati per omogeneità di confronto.

+1

Questo ha funzionato, ma poi ho subito capito che i nomi delle colonne/campi dati sono stati inclusi con OGNI riga, il che rende molto inefficiente , come citato da Keith. Ho intenzione di provare a modificare DataTableConverter e DataRowConverter in modo da non ripetere tutti questi nomi di colonna/campo. – rhyno

+0

@rhyno qual è stata la soluzione finale per non ripetere tutti i nomi di colonna/campo? Ho un'idea di cosa avrei intenzione di fare, ma se l'hai già fatto mi verrebbe risparmiato un po 'di tempo. – DeadlyChambers

5

Prova questo:

public string ConvertDataTabletoString(System.Data.DataTable dt) 
{ 
    System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer(); 
    List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>(); 
    Dictionary<string, object> row; 
    foreach (System.Data.DataRow dr in dt.Rows) 
    { 
     row = new Dictionary<string, object>(); 
     foreach (System.Data.DataColumn col in dt.Columns) 
     { 
      row.Add(col.ColumnName, dr[col]); 
     } 
     rows.Add(row); 
    } 
    return serializer.Serialize(rows); 
} 
1

ho avuto lo stesso problema, il mio servizio WCF non era la formattazione del jSON correttamente durante la conversione da Dataset a jSON. ho ottenuto che funziona utilizzando la seguente soluzione:

using System.ServiceModel.Channels; 
using System.ServiceModel.Web; 

dsData è il mio set di dati

string json = Newtonsoft.Json.JsonConvert.SerializeObject(dsData); 
return WebOperationContext.Current.CreateTextResponse(json, "application/json;charset=utf-8", System.Text.Encoding.UTF8); 

e "Messaggio" sarà il tipo di ritorno.

Problemi correlati