将JSON转换为DataTable
我有以下格式的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);
把下面的扩展方法写到你的项目中
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>();
有一个比这里的其他答案更容易的方法,它需要首先反序列化成ac#类,然后把它变成一个数据表。
使用JSON.NET和代码可以直接进入数据表:
DataTable dt = (DataTable)JsonConvert.DeserializeObject(json, (typeof(DataTable)));
它也可以使用下面的代码来实现。
DataSet data = JsonConvert.DeserializeObject<DataSet>(json);
你可以在这里使用JSON.Net 。 看看JsonConvert.DeserializeObject
方法。
人们并不总是知道反序列化的types。 因此,能够接受任何JSON(包含一些数组)并从中dynamic生成一个表将会很方便。
但是,如果反序列化器不知道在哪里查找要列表的数组,则会出现问题。 发生这种情况时,我们会收到与以下类似的错误消息:
读数据表时意外的JSON令牌。 预计StartArray,得到StartObject。 path“,第1行,位置1。
即使我们给它鼓励,或者相应地准备我们的json,那么数组中的“对象”types仍然可以防止发生列表的出现,而反序列化器不知道如何用行来表示对象等。在这种情况下,会发生类似于以下的错误:
读取DataTable时出现意外的JSON令牌:StartObject。 path'[0] .__元数据',第3行,第19位。
下面的示例JSON包含这两个有问题的function…:
{ "results": [ { "Enabled": true, "Id": 106, "Name": "item 1", }, { "Enabled": false, "Id": 107, "Name": "item 2", "__metadata": { "Id": 4013 } } ] }
那么我们怎样才能解决这个问题,仍然保持不知道衍生types的灵活性?
那么这里是一个简单的方法(假设你很高兴忽略对象types属性,比如上面例子中的__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()); }
我知道这可能是更多的Linq y,并且绝对有0个exception处理,但希望这个概念能传达出来。 我们开始在自己的工作中使用越来越多的服务,这些服务反吐JSON,因此我们可以自由地强制性地input所有内容,因为我很懒惰!
我build议你使用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);