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!
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 –
possibile duplicato del [JSON Come convertire in datatable?] (http://stackoverflow.com/questions/7641004/how-to-convert-json-into-datatable) – wildcat