2013-07-29 13 views
14

Po skonfigurowaniu funkcji WCF do korzystania z serializacji jSON i uwzględnieniu DataTable w jednej z moich umów DataContracts, serializuje ona DataTable do XML przed serializowaniem całego DataContract do jSON. Chcę, aby DataTable były serializowane jako jSON, a nie XML.Jaki jest najlepszy sposób serializacji jSON .NET DataTable w WCF?

Moje pytania są następujące:

  1. Dlaczego to pierwszy serializacji DataTable do XML?
  2. Jak mogę to zrobić, aby przekształcić do JSON?
+0

Witamy w S.O. Co próbowaliście, żeby serializować z Jsonem? –

+0

Rozważ to i zamień dane do JSON http: // stackoverflow.com/questions/17398019/how-to-convert-datatable-to-json-in-c-sharp –

Odpowiedz

13
  1. DataTable jest czystym konstruktem .NET, który nie może być (łatwo) przedstawiony bezstratnie przez JSON. DataTables zawiera wiele dodatkowych informacji, których JSON nie może przechowywać: klucze podstawowe, funkcje autoincs, dopuszcza wartości null, podpis, typ danych, indeksy itp. Serializacja do formatu XML/binarnego to jedyne sposoby serializowania tabeli DataTable przez .NET. Ta serializowana XML DataTable jest następnie serializowana do JSON.

  2. Zastosowanie JSON.NET lub FastJSON konwertować DataTable na równinie, czyste JSON zgodny wersja DataTable, które mogą być spożywane przez każdego klienta JSON, nie tylko klientów .NET WCF. Utracisz wszystkie właściwości niestandardowe DataTable wymienione w punkcie (1) powyżej i uzyskasz tylko parę JSON nazwy/wartości pola. Przechowywanie w ten sposób jest nieefektywne z powodu powielania nazw pól w każdym rzędzie.

Nie należy używać DataTable w DataContract. Jeśli chcesz korzystać z DataTable, a Twoi klienci zawsze będą .NET, serializować DataTable do tablicy bajtów poprzez szeregowanie binarne, a następnie opcjonalnie skompresować wynikowy serializowany strumień bajtów. Ujawnij tablicę bajtów w swoim DataContract. Zapewni to wydajną, w pełni bezstratną wersję DataTable po stronie klienta (po dekompresji i deserializacji binarnej), a nie rozwodnioną wersję JSON DataTable (oferowaną przez (2)) ...

+0

Świetne odpowiedzi. Dziękuję Ci. Moi klienci to nie wszystko .NET i szybko odkryłem wspomniane nieefektywności. Spróbuję zmodyfikować to podejście, aby nie musiałem podawać nazw kolumn/pól w każdym wierszu. – rhyno

+0

Wiem, że jest to stary wątek, ale fastjson wspiera serializację/deserializację z wersji 1.7.7, która została wydana przed czerwcem 2011 roku. Format xml jest nieefektywny, zawiera niewygodny znacznik dla każdego wiersza AND. –

+0

@Keith Blows, a co z serializacją listy DataTables? Jak sugerujesz to zrobić? – Xegara

2

Zgodnie z tabelą na jej stronie głównej, Json.NET jest naprawdę jedyną opcją - można ją szybko uzyskać od NuGet. Na szczęście jest to świetna biblioteka i bardzo łatwa w użyciu.

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

Zauważ, że Rich Strahl ma wielki post z większą ilością szczegółów i obejmuje on również pewne zleceniowe zrobił używać JavaScriptSerializer z (dość obszernych) custom konwerterów dla celów porównawczych.

+1

To zadziałało, ale szybko zorientowałem się, że nazwy kolumn/pól danych są zawarte w KAŻDYM rzędzie, co czyni go bardzo nieefektywnym , jak wspomniał Keith. Mam zamiar spróbować zmodyfikować DataTableConverter i DataRowConverter tak, że nie będę powtarzać wszystkich tych nazw kolumn/pól. – rhyno

+0

@rhyno jakie było Twoje rozwiązanie końcowe, aby nie powtarzać wszystkich nazw kolumn/pól? Mam pomysł, co zamierzam zrobić, ale jeśli już to zrobiłeś, zaoszczędziłoby to trochę czasu. – DeadlyChambers

5

Spróbuj tego:

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

miałem ten sam problem, moja usługa WCF nie formatowanie json prawidłowo podczas konwertowania go z zestawu danych JSON. mam to działa stosując następujące rozwiązanie:

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

dsData jest mój zestaw danych

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

i "Message" będzie zwracany typ.