我需要转换从REST API获得的JSON数据,并将其转换为CSV以便进行分析。问题在于JSON数据不一定遵循相同的内容,因此我无法定义映射类型。这已经成为一项挑战,占用了我太多时间。我已经创建了一些代码,但是由于它在此行上引发了异常,因此它当然不起作用
var data = JsonConvert.DeserializeObject<List<object>>(jsonData);
错误是:
附加信息:无法将当前JSON对象(例如{“ name”:“ value”})反序列化为类型’System.Collections.Generic.List`1 [System.Object]’,因为该类型需要JSON数组(例如[1 ,2,3])正确反序列化。 要解决此错误,可以将JSON更改为JSON数组(例如[1,2,3]),也可以更改反序列化类型,使其成为普通的.NET类型(例如,不像整数这样的原始类型,也不像这样的集合类型。可以从JSON对象反序列化的数组或列表)。还可以将JsonObjectAttribute添加到类型中,以强制其从JSON对象反序列化。 路径“数据”,第2行,位置10。
附加信息:无法将当前JSON对象(例如{“ name”:“ value”})反序列化为类型’System.Collections.Generic.List`1 [System.Object]’,因为该类型需要JSON数组(例如[1 ,2,3])正确反序列化。
要解决此错误,可以将JSON更改为JSON数组(例如[1,2,3]),也可以更改反序列化类型,使其成为普通的.NET类型(例如,不像整数这样的原始类型,也不像这样的集合类型。可以从JSON对象反序列化的数组或列表)。还可以将JsonObjectAttribute添加到类型中,以强制其从JSON对象反序列化。
路径“数据”,第2行,位置10。
请让我知道该如何做。
数据示例就是这样,数据字段可以经常更改,例如第二天可以添加一个新字段,因此我没有创建一个.Net类来映射数据的自由。
{ "data": [ { "ID": "5367ab140026875f70677ab277501bfa", "name": "Happiness Initiatives - Flow of Communication/Process & Efficiency", "objCode": "PROJ", "percentComplete": 100.0, "plannedCompletionDate": "2014-08-22T17:00:00:000-0400", "plannedStartDate": "2014-05-05T09:00:00:000-0400", "priority": 1, "projectedCompletionDate": "2014-12-05T08:10:21:555-0500", "status": "CPL" }, { "ID": "555f452900c8b845238716dd033cf71b", "name": "UX Personalization Think Tank and Product Strategy", "objCode": "PROJ", "percentComplete": 0.0, "plannedCompletionDate": "2015-12-01T09:00:00:000-0500", "plannedStartDate": "2015-05-22T09:00:00:000-0400", "priority": 1, "projectedCompletionDate": "2016-01-04T09:00:00:000-0500", "status": "APR" }, { "ID": "528b92020051ab208aef09a4740b1fe9", "name": "SCL Health System - full Sitecore implementation (Task groups with SOW totals in Planned hours - do not bill time here)", "objCode": "PROJ", "percentComplete": 100.0, "plannedCompletionDate": "2016-04-08T17:00:00:000-0400", "plannedStartDate": "2013-11-04T09:00:00:000-0500", "priority": 1, "projectedCompletionDate": "2013-12-12T22:30:00:000-0500", "status": "CPL" } ] } namespace BusinessLogic { public class JsonToCsv { public string ToCsv(string jsonData, string datasetName) { var data = JsonConvert.DeserializeObject<List<object>>(jsonData); DataTable table = ToDataTable(data); StringBuilder result = new StringBuilder(); for (int i = 0; i < table.Columns.Count; i++) { result.Append(table.Columns[i].ColumnName); result.Append(i == table.Columns.Count - 1 ? "\n" : ","); } foreach (DataRow row in table.Rows) { for (int i = 0; i < table.Columns.Count; i++) { result.Append(row[i].ToString()); result.Append(i == table.Columns.Count - 1 ? "\n" : ","); } } return result.ToString().TrimEnd(new char[] {'\r', '\n'}); } private DataTable ToDataTable<T>( 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; } } }
真正的问题是,您尝试反序列化为,List<object>但是JSON实际上代表一个包含data属性的单个对象,该属性随后包含一个对象列表。这就是为什么您会收到此错误。Json.Net无法将单个对象反序列化为列表。我认为您真正想要做的就是定义一个这样的容器类:
List<object>
data
class Root { public List<Dictionary<string, object>> Data { get; set;} }
然后像这样反序列化:
var data = JsonConvert.DeserializeObject<Root>(jsonData).Data;
然后,您将获得一个字典列表,其中每个字典代表JSON数组中的一项。字典键值对是每个项目中的动态值。然后,您可以像处理其他任何词典一样使用它们。例如,这是转储所有数据的方式:
foreach (var dict in data) { foreach (var kvp in dict) { Console.WriteLine(kvp.Key + ": " + kvp.Value); } Console.WriteLine(); }
小提琴:https : //dotnetfiddle.net/6UaKhJ