Converter JSON para DataTable
Tenho o JSON no seguinte formato:
[
{"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}
]
Como posso converter isso num objecto c# DataTable
como se segue?
---------------------------------------------------------------------
ID | Name | Add | Edit | View | Authorize
---------------------------------------------------------------------
10 | User | true | true | true | true
11 | Group | true | true | true | true
12 | Permission| true | true | true | true
7 answers
List<User> UserList = JsonConvert.DeserializeObject<List<User>>(jsonString);
Escrever de acordo com o método de extensão para o seu projecto
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;
}
Método de extensão de chamadas como
UserList.ToDataTable<User>();
DataTable dt = (DataTable)JsonConvert.DeserializeObject(json, (typeof(DataTable)));
Também pode ser alcançado usando o código abaixo.
DataSet data = JsonConvert.DeserializeObject<DataSet>(json);
Um problema pode surgir no entanto, onde o desertor não sabe onde procurar a matriz para tabular. Quando isso acontece, recebemos uma mensagem de erro semelhante ao seguinte:
Símbolo JSON inesperado quando se lê datável. Esperado StartArray, tenho lançamento estelar. Path", linha 1, posição 1.
Mesmo que lhe demos encorajamento ou preparemos o nosso json de acordo, então os tipos de "objecto" dentro da matriz ainda podem impedir que a tabulação ocorra, onde o desertor não sabe como representar os objectos em termos de linhas, etc. Neste caso, ocorrem erros semelhantes aos seguintes:
Token JSON inesperado ao ler datable: start Tojet. Path "[0].__metadata", linha 3, posição 19.
O exemplo abaixo JSON inclui: ambas as características problemáticas:
{
"results":
[
{
"Enabled": true,
"Id": 106,
"Name": "item 1",
},
{
"Enabled": false,
"Id": 107,
"Name": "item 2",
"__metadata": { "Id": 4013 }
}
]
}
Então, como podemos resolver isso, e ainda manter a flexibilidade de não saber o tipo para ridicularizar?
Bem, aqui está uma abordagem simples que eu inventei (assumindo que você está feliz em ignorar as propriedades do tipo de objeto, tais como _ _ metadados no exemplo acima):
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());
}
Eu sei que isto pode ser mais "LINQy" e não tem nenhum tratamento de excepção, mas espero que o conceito seja transmitido.
Estamos a começar a usar mais e mais serviços no meu trabalho que devolvem o JSON, por isso, libertar-nos de digitar tudo fortemente, é a minha preferência óbvia porque sou preguiçoso!
Podes fazer uso de JSON.Net toma. Dê uma olhada no método JsonConvert.DeserializeObject
.
Recomendo que use JSON.NET . é uma biblioteca de código aberto para serializar e deserializar os seus objectos c# nos objectos json e Json nos objectos .net...
Exemplo De Serialização:
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);
Aqui está outra abordagem sem descontinuidades para converter JSON para datável usando Cinchoo ETL - uma biblioteca de código aberto
A amostra abaixo mostra como converter
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();
}
Espero que ajude.