简体   繁体   中英

Parse Json with multiple objects newtonsoft

I'm attempting to parse a rather convoluted/unnecessarily complicated JSON output using newtonsoft in C# however for some reason my parser always returns null and doesn't elaborate as to exactly why this is the case.

An example of a JSON file I'm trying to parse:

   {
    "response": {
        "success": 1,
        "current_time": 1362339098,
        "prices": {
            "35": { 
                "11": { 
                    "0": { 
                        "current": {
                            "currency": "keys",
                            "value": 39,
                            "value_high": 41,
                            "date": 1357515306 
                        },
                        "previous": { 
                            "currency": "keys",
                            "value": 37,
                            "value_high": 39
                        }
                    }
                },
                "3": { 
                    "0": { 
                        "current": {
                            "currency": "metal",
                            "value": 0.33,
                            "value_high": 0.66
                        }
                    }
                }
            },
            "5002": { 
                "6": {
                    "0": {
                        "current": {
                            "currency": "usd",
                            "value": 0.39,
                            "value_high": 0.42,
                            "date": 1358090106
                        }
                    }
                }
            },                          
            "5022": {
                "6": {
                    "1": { 
                        "current": {
                            "currency": "metal",
                            "value": 1.33,
                            "value_high": 1.55,
                            "date": 1357515175
                        }
                    }
                }
            }
        }
    }
}

And the C# parser I'm using. I run the getCurrentPrices() to return a PriceParser object but instead the object returned is always null.

using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
using System.Diagnostics;

namespace SteamBot
{
    class PriceParser
    {
        //Methods
        public PriceParser updatePrices()
        {
            var json = File.ReadAllText("test.json");
            ParserResult result = JsonConvert.DeserializeObject<ParserResult>(json);
            return result.result;
        }

        public Data currentPrices { get; set; }

        //DATA
        public class Data
        {
            public Response Response { get; set; }
        }

        public class Response 
        {
           public string success { get; set; }
           public string current_time {get; set;}
          public List<Price> prices { get; set;}
        }

        public class Price
        {
            public int defindex { get; set; }
            public int quality { get; set; }
            public Current current { get; set; }
            public Previous previous { get; set; }
        }

        public class Current
        {
            public string currency { get; set; }
            public float value { get; set; }
            public float value_high { get; set; }
            public int date { get; set; }
        }

        public class Previous
        {
            public string currency { get; set; }
            public float value { get; set; }
            public float value_high { get; set; }
            public int date { get; set; }
        }

        protected class ParserResult
        {
            public PriceParser result { get; set; }
        }
    }
}

I'm probably just missing something stupid but for the life of me I can't figure out what, anyone with more JSON wrangling experience know what's going on here?

You are getting null values because your class structure does not match your JSON.

The first issue is that you are deserializing into a ParserResult when you should be using a Data . Data has a response property, matching your JSON. ParserResult does not have this property.

The second issue is that you have defined prices to be a List<Price> , but your JSON does not contain an array. Instead, the JSON structure is actually a series of nested dictionaries.

Try defining your inner classes like this:

public class Data
{
    public Response response { get; set; }
}

public class Response
{
    public int success { get; set; }
    public long current_time { get; set; }
    public IDictionary<int, IDictionary<int, IDictionary<int, Price>>> prices { get; set; }
}

public class Price
{
    public Quote current { get; set; }
    public Quote previous { get; set; }
}

public class Quote
{
    public string currency { get; set; }
    public decimal value { get; set; }
    public decimal value_high { get; set; }
    public long date { get; set; }
}

Then, in your updatePrices method you can deserialize like this:

public PriceParser updatePrices()
{
    var json = File.ReadAllText("test.json");
    currentPrices = JsonConvert.DeserializeObject<Data>(json);
    return this;
}

Here is how you would dump out the data:

PriceParser parser = new PriceParser();
parser.updatePrices();

foreach (var defindex in parser.currentPrices.response.prices)
{
    Console.WriteLine("defindex: " + defindex.Key);
    foreach (var quality in defindex.Value)
    {
        Console.WriteLine("\t quality: " + quality.Key);
        foreach (var price in quality.Value)
        {
            Console.WriteLine("\t\t index: " + price.Key);
            Console.WriteLine("\t\t\t current price:");
            Console.WriteLine("\t\t\t\t currency: " + price.Value.current.currency);
            Console.WriteLine("\t\t\t\t value: " + price.Value.current.value);
            Console.WriteLine("\t\t\t\t value_high: " + price.Value.current.value_high);
            if (price.Value.previous != null)
            {
                Console.WriteLine();
                Console.WriteLine("\t\t\t previous price:");
                Console.WriteLine("\t\t\t\t currency: " + price.Value.previous.currency);
                Console.WriteLine("\t\t\t\t value: " + price.Value.previous.value);
                Console.WriteLine("\t\t\t\t value_high: " + price.Value.previous.value_high);
            }
        }
    }
}

And here is the output of the above:

defindex: 35
         quality: 3
                 index: 0
                         current price:
                                 currency: metal
                                 value: 0.33
                                 value_high: 0.66
         quality: 11
                 index: 0
                         current price:
                                 currency: keys
                                 value: 39
                                 value_high: 41

                         previous price:
                                 currency: keys
                                 value: 37
                                 value_high: 39
defindex: 5002
         quality: 6
                 index: 0
                         current price:
                                 currency: usd
                                 value: 0.39
                                 value_high: 0.42
defindex: 5022
         quality: 6
                 index: 1
                         current price:
                                 currency: metal
                                 value: 1.33
                                 value_high: 1.55

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM