2012-08-16 33 views
27

tengo JSON en el siguiente formato:Convertir JSON para DataTable

[ 
    {"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ómo puedo convertir eso en un objeto de C# DataTable de la siguiente manera?

--------------------------------------------------------------------- 
ID | Name  | Add | Edit | View | Authorize 
--------------------------------------------------------------------- 
10 | User  | true | true | true | true 
11 | Group  | true | true | true | true 
12 | Permission| true | true | true | true 
+0

Mire la respuesta a esta pregunta [1] como referencia. [1]: http://stackoverflow.com/questions/2246694/how-to-convert-json-object-to-custom-c-sharp-object –

+1

posible duplicado de [Cómo convertir JSON en tabla de datos?] (http://stackoverflow.com/questions/7641004/how-to-convert-json-into-datatable) – wildcat

Respuesta

31

Deserialize su jsonString a alguna clase

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

Escribir siguiente extension method a su proyecto

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 extensión

llamada Al igual que

UserList.ToDataTable<User>();

+1

¿Qué es JsonConvert? ¿Debo incluir cualquier espacio de nombres? Obtiene el error – Nithesh

+0

Sí ... Necesita referir el dll [desde aquí] (http://json.codeplex.com/) –

+0

Estoy tratando de usar el método de extensión anterior - Sin errores en la compilación. Pero obtengo un error de compilación: "Mensaje de error del compilador: CS0121: la llamada es ambigua entre los siguientes métodos o propiedades: 'ExtensionHelpers.ToDataTable <_Default.Jobs> (System.Collections.Generic.IList <_Default.Jobs>)' y 'ExtensionHelpers.ToDataTable <_Default.Jobs> (System.Collections.Generic.IList <_Default.Jobs>)' "¿Tiene alguna idea de lo que podría estar causando? @PravinPawar –

1

Puede hacer uso de JSON.Net aquí. Eche un vistazo al método JsonConvert.DeserializeObject.

-1

Te recomiendo que uses JSON.NET. es una biblioteca de código abierto para serializar y deserializar su C# objetos en JSON y objetos JSON en objetos .NET ...

serialización Ejemplo:

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); 
+0

¿Cómo podemos hacer esto para la lista ? – Jesuraja

+1

¿Por qué está esto downvoted? JSON.NET es una opción viable –

37

Hay un método más fácil que las otras respuestas aquí, que requieren primera deserializar en una clase C#, y luego convertirlo en una tabla de datos.

Es posible ir directamente a una tabla de datos, con JSON.NET y código como este:

DataTable dt = (DataTable)JsonConvert.DeserializeObject(json, (typeof(DataTable))); 
+1

Esto arroja una JsonSerializationException cuando trato de serializar un objeto Json – Guerrilla

+0

@Guerrilla ¿Cuál es el mensaje dentro de la excepción? ¿has verificado dos veces que el json está bien formado? – Kyle

+0

Fue mi culpa, primero tuve que agregar el objeto a una matriz y luego funcionó bien. – Guerrilla

14

También se puede lograr mediante el siguiente código.

DataSet data = JsonConvert.DeserializeObject<DataSet>(json); 
+1

es fácil y conveniente – abhi

2

Uno no siempre sabe el tipo en el que deserializar. Por lo tanto, sería útil poder tomar cualquier JSON (que contenga alguna matriz) y producir dinámicamente una tabla a partir de eso.

Sin embargo, puede surgir un problema cuando el deserializador no sabe dónde buscar la matriz para tabular. Cuando esto sucede, obtenemos un mensaje de error similar al siguiente:

Token JSON inesperado al leer DataTable. Se esperaba StartArray, obtuvo StartObject. Path '', línea 1, posición 1.

Incluso si damos viene estímulo o preparar nuestra JSON en consecuencia, a continuación, los tipos de "objeto" dentro de la matriz todavía se puede evitar que se produzca la tabulación, donde el deserializer no lo hace saber cómo representar los objetos en términos de filas, etc. En este caso, se producen errores similares a los siguientes:

Token JSON inesperado al leer DataTable: StartObject. Ruta '[0] .__ metadata', línea 3, posición 19.

El siguiente ejemplo JSON incluye estas dos características problemáticas ...:

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

Entonces, ¿cómo podemos resolver esto y aún así mantener la flexibilidad de no saber el tipo de derialización?

Bueno aquí es un método simple que se me ocurrió (suponiendo que están dispuestos a pasar por alto las propiedades de tipo de objeto, como __metadata en el ejemplo anterior):

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

Sé que esto podría ser más Linq y tiene absolutamente 0 manejo de excepciones, pero ojalá se transmita el concepto. Estamos comenzando a utilizar más y más servicios en mi trabajo que escupió JSON, por lo que nos liberamos de todo lo que escribimos fuertemente, es mi obvia preferencia porque soy flojo.