将JSON反序列化为对象时出错 [英] Error when deserializing JSON to Object

查看:296
本文介绍了将JSON反序列化为对象时出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要转换从REST API获得的JSON数据,并将其转换为CSV以便进行某些分析.问题在于JSON数据不一定遵循相同的内容,因此我无法定义映射类型.这已经成为一项挑战,占用了我太多时间.我已经创建了一些代码,但是当然不起作用,因为它会在此行上引发异常

I need to convert JSON data that I get from a REST API and convert them to CSV for some analytic. The problem is that the JSON data do not necessarily follow the same content, so I can't define a type for mapping. This has become a challenge that is taking too much of my time. I have already created some code, but of course it is not working as it throws exception on this line

var data = JsonConvert.DeserializeObject<List<object>>(jsonData);

错误是:

其他信息:无法反序列化当前JSON对象 (例如{"name":"value"}) 'System.Collections.Generic.List`1 [System.Object]',因为类型 需要JSON数组(例如[1,2,3])才能正确反序列化.

Additional information: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[System.Object]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.

要解决此错误,可以将JSON更改为JSON数组(例如[1,2,3]),也可以更改反序列化类型,使其成为普通的.NET类型(例如,不是整数之类的原始类型,而不是可以从JSON对象反序列化的集合类型(如数组或List).还可以将JsonObjectAttribute添加到类型中,以强制其从JSON对象反序列化.

To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.

路径数据",第2行,位置10.

Path 'data', line 2, position 10.

请让我知道该怎么做.

please let me know what I can do to get this going.

一个数据示例就是这样,数据字段可以经常更改,例如第二天可以添加一个新字段,因此我没有创建.Net类来映射该字段的自由.数据.

A sample of data would be like this, the fields of data can change very often, for example a new field can be added the next day, so I don't have the liberty to create a .Net class to map the data.

{
  "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无法将单个对象反序列化为列表.我认为您真正想要做的就是定义一个这样的容器类:

The real issue here is that you are trying to deserialize into a List<object> but your JSON actually represents a single object containing a data property which then contains a list of objects. That is why you are getting this error. Json.Net can't deserialize a single object into a list. I think what you really want to do is define a container class like this:

class Root
{
    public List<Dictionary<string, object>> Data { get; set;}
}

然后像这样反序列化:

var data = JsonConvert.DeserializeObject<Root>(jsonData).Data;

然后,您将获得一个词典列表,其中每个词典代表JSON数组中的一项.字典键值对是每个项目中的动态值.然后,您可以像处理其他任何词典一样使用它们.例如,这是转储所有数据的方法:

You will then end up with a list of dictionaries, where each dictionary represents one item in the JSON array. The dictionary key-value pairs are the dynamic values in each item. You can then work with these as you would with any other dictionary. For example, here is how you would dump out all the data:

foreach (var dict in data)
{
    foreach (var kvp in dict)
    {
        Console.WriteLine(kvp.Key + ": " + kvp.Value);
    }
    Console.WriteLine();
}

提琴: https://dotnetfiddle.net/6UaKhJ

这篇关于将JSON反序列化为对象时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆