次の形式の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
Jsonstringを何らかのクラスにデシリアライズします
List<User> UserList = JsonConvert.DeserializeObject<List<User>>(jsonString);
次の extension method をプロジェクトに書き込みます
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>();
ここにある他の回答よりも簡単な方法があります。最初にc#クラスにデシリアライズし、次にそれをデータテーブルに変換する必要があります。
JSON.NETと次のようなコードを使用して、データテーブルに直接移動することができます。
DataTable dt = (DataTable)JsonConvert.DeserializeObject(json, (typeof(DataTable)));
以下のコードを使用しても実現できます。
DataSet data = JsonConvert.DeserializeObject<DataSet>(json);
逆シリアル化する型が常にわからない。したがって、JSON(配列を含む)を取得して、そこから動的にテーブルを生成できると便利です。
ただし、デシリアライザーが表を作成する配列を探す場所を知らない場合、問題が発生する可能性があります。これが発生すると、次のようなエラーメッセージが表示されます。
DataTableの読み取り時に予期しないJSONトークン。 StartArrayが必要で、StartObjectを取得しました。パス ''、行1、位置1。
励ましを与えたり、それに応じてjsonを準備したとしても、配列内の「オブジェクト」型は、デシリアライザーがオブジェクトを行などで表現する方法を知らない場合でも、集計の発生を防ぐことができます。 、次のようなエラーが発生します。
DataTableの読み取り時に予期しないJSONトークン:StartObject。パス '[0] .__ metadata'、行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を吐き出すサービスをますます使用し始めているので、私は怠け者なので、すべてを強く型付けすることから自由になります!
Cinchoo ETL -オープンソースライブラリを使用してJSONをDatatableに変換する別のシームレスなアプローチを次に示します。
以下のサンプルは変換方法を示しています
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();
}
それが役に立てば幸い。
ここで JSON.Net を使用できます。 JsonConvert.DeserializeObject
メソッドを見てください。
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);