Какой лучший способ для jSON сериализации .NET DataTable в WCF?

Когда я настраиваю WCF для использования сериализации jSON и включаю DataTable в один из моих DataContracts, он сериализует DataTable в XML, прежде чем сериализует весь DataContract в jSON. Я хочу, чтобы DataTable сериализовался как jSON, а не XML.

Мои вопросы:

  • Почему он сначала сериализует DataTable в XML?
  • Как я могу получить его для сериализации в jSON вместо?

Ответ 1

  • DataTable - это чистая .NET-конструкция, которая не может быть (легко) представлена ​​без потерь JSON. В DataTables содержится много дополнительной информации, которую JSON не может хранить: Первичные ключи, автоинкременты, разрешить нули, заголовок, тип данных, индексы и т.д. Сериализация в XML/Binary - это единственный способ, с помощью которого DataTable может быть сериализована .NET. Этот XML-сериализованный DataTable затем сериализуется в JSON.

  • Используйте JSON.NET или FastJSON преобразовать DataTable в чистую JSON-совместимую версию DataTable, которая может быть использована любым клиентом JSON, а не только .NET WCF-клиентами. Вы потеряете все пользовательские свойства DataTable, упомянутые в (1) выше, и получите только пару JSON с именем/значением поля. Хранение таким образом неэффективно из-за дублирования имен полей в каждой строке.

Не используйте DataTable в DataContract. Если вы хотите, чтобы преимущества DataTable и ваших клиентов всегда были .NET, сериализуйте DataTable в массив байтов через двоичную сериализацию и затем произвольно сжимайте результирующий последовательный поток байтов. Выведите массив байтов в свой DataContract. Это даст вам эффективную, полностью без потерь версию DataTable на стороне клиента (после декомпрессии и двоичную десериализацию), а не раздутую версию JSON DataTable (как предложено (2))...

Ответ 2

Попробуйте следующее:

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);
}

Ответ 3

В соответствии с графиком на его домашней странице Json.NET - это ваш единственный вариант - вы можете быстро получить его из NuGet. К счастью, это отличная библиотека и очень проста в использовании.

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

Обратите внимание, что Rich Strahl имеет отличный пост с более подробной информацией, а также включает в себя некоторые пользовательские работы, которые он использовал для использования JavaScriptSerializer с ( довольно обширные) пользовательские преобразователи для сравнения.

Ответ 4

У меня была такая же проблема, моя служба wcf не форматировала json правильно, преобразовывая ее из Dataset в Json. Я получил его работу, используя следующее решение:

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

dsData - это мой набор данных

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

и "Сообщение" будет типом возврата.