我有以下格式的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
答案 0 :(得分:52)
这里有一个比其他答案更简单的方法,它需要首先反序列化为c#类,然后将其转换为数据表。
可以直接转到数据表,使用JSON.NET和这样的代码:
DataTable dt = (DataTable)JsonConvert.DeserializeObject(json, (typeof(DataTable)));
答案 1 :(得分:41)
将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>();
答案 2 :(得分:18)
也可以使用以下代码实现。
DataSet data = JsonConvert.DeserializeObject<DataSet>(json);
答案 3 :(得分:5)
一个人并不总是知道要反序列化的类型。因此,能够获取任何JSON(包含一些数组)并从中动态生成表格将非常方便。
然而,可能出现一个问题,即反序列化器不知道在哪里查找要列表的数组。发生这种情况时,我们会收到类似于以下内容的错误消息:
读取DataTable时出现意外的JSON令牌。预期的StartArray,得到了StartObject。路径'',第1行,第1位。
即使我们给予鼓励或相应地准备我们的json,那么数组中的“对象”类型仍然可以防止制表,其中反序列化器不知道如何以行等方式表示对象。在这种情况下,会发生类似于以下的错误:
读取DataTable时出现意外的JSON令牌:StartObject。路径'[0] .__元数据',第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,因此我很自然地强力输入所有内容,这是我明显的偏好,因为我很懒惰!
答案 4 :(得分:1)
您可以在此处使用JSON.Net。看看JsonConvert.DeserializeObject
方法。
答案 5 :(得分:1)
我建议您使用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);
答案 6 :(得分:1)
json = File.ReadAllText(System.AppDomain.CurrentDomain.BaseDirectory + "App_Data\\" +download_file[0]);
DataTable dt = (DataTable)JsonConvert.DeserializeObject(json, (typeof(DataTable)));
答案 7 :(得分:0)
这是使用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();
}
希望有帮助。