Error when deserializing JSON to Object

前端 未结 7 2000
别跟我提以往
别跟我提以往 2020-12-18 04:29

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 conten

相关标签:
7条回答
  • 2020-12-18 04:44

    You are trying to deserialize into a List but your JSON actually represents a single object containing a data property containing list of objects. That is why you are getting this error. Json.Net can't deserialize a single object into a list.

    Please try this:Create a class which contain single property on datatype Object and pass this class for deserialization.

    class Parent
    {
        public object Data { get; set;}
    }
    

    Then deserialize like this:

    var output = JsonConvert.DeserializeObject<Parent>(jsonData);
    
    0 讨论(0)
  • 2020-12-18 04:45

    As far as I can tell, more recent versions of Newtonsoft can actually do this now, no additional work required.

    I was working with the binary version however, and this did still have the issue - I had a test where you could configure to use binary or json, and the json version worked just fine, but the binary complained about not getting an array type.

    I started using the BsonDataReader for this, and was looking through the properties and methods on it to see how I could best look at the contents, and lo and behold, this had a property called:

    reader.ReadRootValueAsArray 
    

    Setting this to 'true' did the trick.

    0 讨论(0)
  • 2020-12-18 04:48

    Since you're trying to deserialize an object type into a list type, it won't deseralize directly.

    You can do this:

    var data = JsonConvert.DeserializeObject<ObjectDataList>(jsonData);
    var rows = new List<DeserializedData>();
    
    foreach (dynamic item in data)
    {
        var newData = new DeserializedData();
        foreach (dynamic prop in item)
        {
             var row = new KeyValuePair<string, string>
             (prop.Name.ToString(), prop.Value.ToString());
             newData.Add(row);
        }
        rows.Add(newData);
    }
    

    Here are new classes

    //class for key value type data
    
    class DeserializedData
    {
        List<KeyValuePair<string, string>> NewData = 
        new List<KeyValuePair<string, string>>();
    
        internal void Add(KeyValuePair<string, string> row)
        {
            NewData.Add(row);
        }
    }
    
    
    [DataContract]
    class ObjectDataList
    {
        [DataMember(Name ="data")]
        List<object> Data { get; set; }
        public IEnumerator<object> GetEnumerator()
        {
            foreach (var d in Data)
            {
                yield return d;
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-18 04:53

    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;}
    }
    

    Then deserialize like this:

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

    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();
    }
    

    Fiddle: https://dotnetfiddle.net/6UaKhJ

    0 讨论(0)
  • 2020-12-18 05:02

    What you're looking for is the dynamic type. Though unrelated, this answer contains much of the information on how you'll be able to iterate through the changing properties on your object.

    You will need to add some additional work to figure out how to handle your result when it is an array versus a single object as your error shows us. However, this is a good first step for you.

    Basically, a dynamic object is a Dictionary, much like how a JSON object is treated in JavaScript. You just need to iterate through each of the KeyValuePair objects within the main object and go through their properties.

    var data = JsonConvert.DeserializeObject<dynamic>(jsonData);
    var rows = new List<string>();
    
    // Go through the overall object, and get each item in 
    // the array, or property in a single object.
    foreach (KeyValuePair<string, object> item in data)
    {
        dynamic obj = item.Value;
        var row = "";
    
        // Perhaps add a check here to see if there are more
        // properties (if it is an item in an array). If not
        // then you are working with a single object, and each
        // item is a property itself.
        foreach (KeyValuePair<string, object> prop in obj)
        {
            // Very dummy way to demo adding to a CSV
            string += prop.Value.ToString() + ",";
        }
    
        rows.Add(string);
    }
    

    This is far from a complete example, but we don't have enough information to go on to help you finish what you're trying to do.

    0 讨论(0)
  • 2020-12-18 05:03

    If your data is dynamic so try a dynamic list:

    using System.Web.Script.Serialization;
    
    JavaScriptSerializer jss = new JavaScriptSerializer();
    var d=jss.Deserialize<dynamic>(str);
    
    0 讨论(0)
提交回复
热议问题