Конвертировать JSON в DataTable

c# json datatable

192014 просмотра

7 ответа

У меня есть JSON в следующем формате:

[
    {"id":"10","name":"User","add":false,"edit":true,"authorize":true,"view":true},
    {"id":"11","name":"Group","add":true,"edit":false,"authorize":false,"view":true},
    {"id":"12","name":"Permission","add":true,"edit":true,"authorize":true,"view":true}
]

Как я могу преобразовать это в объект C # DataTableследующим образом?

---------------------------------------------------------------------
ID    |  Name     |  Add    |   Edit  | View   | Authorize
---------------------------------------------------------------------
10    | User      | true    |  true   | true   |  true
11    | Group     | true    |  true   | true   |  true
12    | Permission| true    |  true   | true   |  true
Автор: Nithesh Источник Размещён: 13.11.2019 11:47

Ответы (7)


43 плюса

Решение

Десериализовать вашу jsonstring в некоторый класс

List<User> UserList = JsonConvert.DeserializeObject<List<User>>(jsonString);

Напишите следующий метод расширения для вашего проекта

public static DataTable ToDataTable<T>(this IList<T> data)
{
    PropertyDescriptorCollection props =
    TypeDescriptor.GetProperties(typeof(T));
    DataTable table = new DataTable();
    for(int i = 0 ; i < props.Count ; i++)
    {
    PropertyDescriptor prop = props[i];
    table.Columns.Add(prop.Name, prop.PropertyType);
    }
    object[] values = new object[props.Count];
    foreach (T item in data)
    {
    for (int i = 0; i < values.Length; i++)
    {
        values[i] = props[i].GetValue(item);
    }
    table.Rows.Add(values);
    }
    return table;        
}

Вызов метода расширения как

UserList.ToDataTable<User>();
Автор: Pravin Pawar Размещён: 16.08.2012 07:00

61 плюса

Здесь есть более простой метод, чем другие ответы, которые требуют сначала десериализации в класс ac #, а затем преобразования его в datatable.

Можно перейти непосредственно к таблице данных с помощью JSON.NET и кода, подобного этому:

DataTable dt = (DataTable)JsonConvert.DeserializeObject(json, (typeof(DataTable)));
Автор: Kyle Размещён: 03.12.2014 10:05

21 плюса

Это также может быть достигнуто с помощью приведенного ниже кода.

DataSet data = JsonConvert.DeserializeObject<DataSet>(json);
Автор: Mohammed Ghouse Размещён: 06.02.2015 03:45

7 плюса

Не всегда известен тип, в который нужно десериализоваться. Поэтому было бы удобно иметь возможность взять любой JSON (который содержит некоторый массив) и динамически создать таблицу из этого.

Однако может возникнуть проблема, когда десериализатор не знает, где искать массив для табулирования. Когда это происходит, мы получаем сообщение об ошибке, подобное следующему:

Неожиданный токен JSON при чтении DataTable. Ожидаемый StartArray, получил StartObject. Путь '', строка 1, позиция 1.

Даже если мы дадим ему поощрение или подготовим наш json соответствующим образом, тогда типы «объектов» в массиве все еще могут предотвратить возникновение табуляции, когда десериализатор не знает, как представлять объекты в виде строк и т. Д. В этом случае возникают ошибки, подобные следующим:

Неожиданный токен JSON при чтении DataTable: StartObject. Путь '[0] .__ метаданные', строка 3, позиция 19.

Приведенный ниже пример JSON включает в себя обе эти проблемные функции:

{
  "results":
  [
    {
      "Enabled": true,
      "Id": 106,
      "Name": "item 1",
    },
    {
      "Enabled": false,
      "Id": 107,
      "Name": "item 2",
      "__metadata": { "Id": 4013 }
    }
  ]
}

Итак, как мы можем решить эту проблему и при этом сохранить гибкость, не зная, какой тип дериализовать?

Хорошо, вот простой подход, который я предложил (предполагая, что вы счастливы игнорировать свойства типа объекта, такие как __metadata в приведенном выше примере):

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Data;
using System.Linq;
...

public static DataTable Tabulate(string json)
{
    var jsonLinq = JObject.Parse(json);

    // Find the first array using Linq
    var srcArray = jsonLinq.Descendants().Where(d => d is JArray).First();
    var trgArray = new JArray();
    foreach (JObject row in srcArray.Children<JObject>())
    {
        var cleanRow = new JObject();
        foreach (JProperty column in row.Properties())
        {
            // Only include JValue types
            if (column.Value is JValue)
            {
                cleanRow.Add(column.Name, column.Value);
            }
        }

        trgArray.Add(cleanRow);
    }

    return JsonConvert.DeserializeObject<DataTable>(trgArray.ToString());
}

Я знаю, что это может быть больше "LINQy" и имеет абсолютно нулевую обработку исключений, но, надеюсь, концепция передана.

Мы начинаем использовать все больше и больше сервисов на моей работе, которые наплевывают на JSON, поэтому я полностью освобождаюсь от строгой типизации, потому что я ленив!

Автор: ne1410s Размещён: 21.01.2016 11:18

1 плюс

Вы можете использовать JSON.Net здесь. Посмотрите на JsonConvert.DeserializeObjectметод.

Автор: danish Размещён: 16.08.2012 06:02

1 плюс

Я рекомендую вам использовать JSON.NET . это библиотека с открытым исходным кодом для сериализации и десериализации ваших объектов c # в объекты json и Json в объекты .net ...

Пример сериализации:

Product product = new Product();
product.Name = "Apple";
product.Expiry = new DateTime(2008, 12, 28);
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };

string json = JsonConvert.SerializeObject(product);
//{
//  "Name": "Apple",
//  "Expiry": new Date(1230422400000),
//  "Price": 3.99,
//  "Sizes": [
//    "Small",
//    "Medium",
//    "Large"
//  ]
//}

Product deserializedProduct = JsonConvert.DeserializeObject<Product>(json);
Автор: Talha Размещён: 16.08.2012 06:50

1 плюс

Вот еще один плавный подход к преобразованию JSON в Datatable с использованием Cinchoo ETL - библиотеки с открытым исходным кодом.

Пример ниже показывает, как конвертировать

string json = @"[
{""id"":""10"",""name"":""User"",""add"":false,""edit"":true,""authorize"":true,""view"":true},
{ ""id"":""11"",""name"":""Group"",""add"":true,""edit"":false,""authorize"":false,""view"":true},
{ ""id"":""12"",""name"":""Permission"",""add"":true,""edit"":true,""authorize"":true,""view"":true}
]";

using (var r = ChoJSONReader.LoadText(json))
{
    var dt = r.AsDataTable();
}

Надеюсь, это поможет.

Автор: RajN Размещён: 31.07.2018 03:47
32x32