2012-08-16 17 views
27

ho JSON nel seguente formato:Converti JSON per 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} 
] 

Come posso convertire in un oggetto C# DataTable come 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 
+0

Si prega di guardare la risposta a [questo] [1] domanda come riferimento. [1]: http://stackoverflow.com/questions/2246694/how-to-convert-json-object-to-custom-c-sharp-object –

+1

possibile duplicato del [JSON Come convertire in datatable?] (http://stackoverflow.com/questions/7641004/how-to-convert-json-into-datatable) – wildcat

risposta

31

deserializzare tua jsonstring a qualche classe

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

Scrivi seguente extension method al progetto

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;   
} 
metodo di estensione

chiamata come

UserList.ToDataTable<User>();

+1

Che cos'è JsonConvert? Devo includere qualsiasi spazio dei nomi? si ottiene errore – Nithesh

+0

Sì ... È necessario fare riferimento alla dll [da qui] (http://json.codeplex.com/) –

+0

Sto tentando di utilizzare il metodo di estensione sopra riportato - Nessun errore sulla compilazione. Ma ottengo un errore di compilazione: "Messaggio di errore del compilatore: CS0121: la chiamata è ambigua tra i seguenti metodi o proprietà: 'ExtensionHelpers.ToDataTable <_Default.Jobs> (System.Collections.Generic.IList <_Default.Jobs>)' e 'ExtensionHelpers.ToDataTable <_Default.Jobs> (System.Collections.Generic.IList <_Default.Jobs>)' "Hai idea di cosa potrebbe causarlo? @PravinPawar –

1

Qui è possibile utilizzare JSON.Net. Dai uno sguardo al metodo JsonConvert.DeserializeObject.

-1

Vi consiglio di utilizzare JSON.NET. è una libreria open source per serializzare e deserializzare il vostro C# oggetti in JSON e JSON oggetti in oggetti .NET ...

serializzazione Esempio:

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

Come possiamo fare questo per l'elenco ? – Jesuraja

+1

Perché è down down? JSON.NET è un'opzione valida –

37

C'è un metodo più semplice rispetto alle altre risposte qui, che richiedono prima deserializzazione in una classe C#, e poi trasformandolo in un DataTable.

È possibile accedere direttamente a un datatable, con JSON.NET e codice come questo:

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

Questo genera una JSONSerializationException per me durante il tentativo di serializzare un oggetto Json – Guerrilla

+0

@Guerrilla Qual è il messaggio all'interno dell'eccezione? hai controllato due volte che il JSON è ben formato? – Kyle

+0

È stata colpa mia, ho dovuto prima aggiungere l'oggetto a un array e poi ha funzionato correttamente. – Guerrilla

14

Può anche essere ottenuto usando sotto codice.

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

è facile e conveniente – abhi

2

Uno non sa sempre il tipo in cui deserializzare. Quindi sarebbe utile poter prendere qualsiasi JSON (che contenga qualche array) e generare dinamicamente una tabella da quella.

Tuttavia, è possibile che si verifichi un problema, in cui il deserializzatore non sa dove cercare la matrice da tabellare. Quando ciò accade, viene visualizzato un messaggio di errore simile al seguente:

Token JSON inaspettato durante la lettura di DataTable. Expected StartArray, ha ottenuto StartObject. Path '', riga 1, posizione 1.

Anche se diamo venire incoraggiamento o preparare nostra json conseguenza, quindi tipi "oggetto" all'interno della matrice può ancora impedire tabulazione si verifichi, dove il deserializzatore no sapere come rappresentare gli oggetti in termini di righe, ecc. In questo caso, si verificano errori simili ai seguenti:

Token JSON inaspettato durante la lettura di DataTable: StartObject. Percorso "[0] .__ metadata", riga 3, posizione 19.

Il seguente esempio JSON include entrambe queste caratteristiche problematiche ...:

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

Quindi, come possiamo risolvere questo, e ancora mantenere la flessibilità di non conoscere il tipo in cui derialize?

Beh qui è un approccio semplice mi è venuta (supponendo che si sono felice di ignorare le proprietà oggetto di tipo, come ad esempio __metadata nell'esempio di cui sopra):

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

So che questo potrebbe essere più Linq y e ha assolutamente 0 gestione delle eccezioni, ma si spera che il concetto venga trasmesso. Stiamo iniziando a utilizzare sempre più servizi nel mio lavoro che sputano JSON, liberandoci così di scrivere con forza ogni cosa, è la mia ovvia preferenza perché sono pigro!