4

I have a JSON response which looks like this:

{
"success": true,
"more": false,
"results_html": "a lot of html in here",
"listinginfo": {
    "637640274112277168": {
        "listingid": "637640274112277168",
        "price": 50,
        "fee": 7,
        "publisher_fee_app": 730,
        "publisher_fee_percent": "0.10000000149011612",
        "currencyid": "2005",
        "steam_fee": 2,
        "publisher_fee": 5,
        "converted_price": 1,
        "converted_fee": 2,
        "converted_currencyid": "2003",
        "converted_steam_fee": 1,
        "converted_publisher_fee": 1,
        "converted_price_per_unit": 1,
        "converted_fee_per_unit": 2,
        "converted_steam_fee_per_unit": 1,
        "converted_publisher_fee_per_unit": 1,
        "asset": {
            "currency": 0,
            "appid": 730,
            "contextid": "2",
            "id": "6542776191",
            "amount": "1"
        }
    },
    "194035710805671301": {
        "listingid": "194035710805671301",
        "price": 0,
        "fee": 0,
        "publisher_fee_app": 730,
        "publisher_fee_percent": "0.10000000149011612",
        "currencyid": "2001",
        "asset": {
            "currency": 0,
            "appid": 730,
            "contextid": "2",
            "id": "6825071309",
            "amount": "0"
        }

    },

  }//end listinginfo
 //more fields here..
}

I Need to get the info just from the "listinginfo" node and add them to a dictionary<string, NewListedItem> where string would be for example: "637640274112277168", and the list will be of type "NewListedItem", containing all the info from that subnode. My classes look like that:

class listinginfo
{
    public Dictionary<string, NewListedItem> Items;

}
class Asset
{
    public string currency { get; set; }
    public string appid { get; set; }
    public string contextid { get; set; }
    public string id { get; set; }
    public string amount { get; set; }
}
class NewListedItem
{

    public string listingid { get; set; }
    public string price { get; set; }
    public string fee { get; set; }
    public string publisher_fee_app { get; set; }
    public string publisher_fee_percent { get; set; }
    public string steam_fee { get; set; }
    public string publisher_fee { get; set; }
    public string converted_price { get; set; }
    public string converted_fee { get; set; }
    public string converted_currencyid { get; set; }
    public string converted_steam_fee { get; set; }
    public string converted_publisher_fee { get; set; }
    public string converted_fee_per_unit { get; set; }
    public string converted_steam_fee_per_unit { get; set; }
    public string converted_publisher_fee_per_unit { get; set; }
    public Asset asset { get; set; }


}

How can i achieve this?

ddacot
  • 1,212
  • 3
  • 14
  • 40
  • If you're willing to use a third-party library JSon.Net could make this easier. See this closely related question... http://stackoverflow.com/questions/15789539/deserialize-array-of-key-value-pairs-using-json-net – dazedandconfused Jul 08 '16 at 12:19
  • @dazedandconfused seeing as the question is *tagged* [tag:json.net], I expect that is fine... – Marc Gravell Jul 08 '16 at 12:20
  • 2
    @MarcGravell - Oops, so it does. No more commenting for me until the coffee starts doing its thing. – dazedandconfused Jul 08 '16 at 12:28

3 Answers3

1

So I wasn't able to do this in a clean way, but I believe this is what you are looking for:

 var jsonString = @"{
            'success': true,
            'more': false,
            'results_html': 'a lot of html in here',
            'listinginfo': {
                '637640274112277168': {
                    'listingid': '637640274112277168',
                    'price': 50,
                    'fee': 7,
                    'publisher_fee_app': 730,
                    'publisher_fee_percent': '0.10000000149011612',
                    'currencyid': '2005',
                    'steam_fee': 2,
                    'publisher_fee': 5,
                    'converted_price': 1,
                    'converted_fee': 2,
                    'converted_currencyid': '2003',
                    'converted_steam_fee': 1,
                    'converted_publisher_fee': 1,
                    'converted_price_per_unit': 1,
                    'converted_fee_per_unit': 2,
                    'converted_steam_fee_per_unit': 1,
                    'converted_publisher_fee_per_unit': 1,
                    'asset': {
                                        'currency': 0,
                        'appid': 730,
                        'contextid': '2',
                        'id': '6542776191',
                        'amount': '1'
                    }
                },
                '194035710805671301': {
                    'listingid': '194035710805671301',
                    'price': 0,
                    'fee': 0,
                    'publisher_fee_app': 730,
                    'publisher_fee_percent': '0.10000000149011612',
                    'currencyid': '2001',
                    'asset': {
                            'currency': 0,
                            'appid': 730,
                            'contextid': '2',
                            'id': '6825071309',
                            'amount': '0'
                        }

                },
                }
        }";
        var json = JObject.Parse(jsonString);

        List<JToken> results = json["listinginfo"].Children().Children().ToList();
        var dictionaryResults = new ListingInfo();

        foreach (var token in results)
        {
            var info = JsonConvert.DeserializeObject<NewListedItem>(token.ToString());

            List<NewListedItem> listInfo = new List<NewListedItem>();
            listInfo.Add(info);

            dictionaryResults.Items = new Dictionary<string, List<NewListedItem>>();
            dictionaryResults.Items.Add(info.Listingid, listInfo);
        }

I also modified your class's property names a little bit :

 public class Asset
    {
        public string Currency { get; set; }
        public string Appid { get; set; }
        public string Contextid { get; set; }
        public string Id { get; set; }
        public string Amount { get; set; }
    }
    public class NewListedItem
    {

        public string Listingid { get; set; }
        public string Price { get; set; }
        public string Fee { get; set; }
        [JsonProperty("publisher_fee_app")]
        public string PublisherFeeApp { get; set; }
        [JsonProperty("publisher_fee_percent")]
        public string PublisherFeePercent { get; set; }
        [JsonProperty("steam_fee")]
        public string SteamFee { get; set; }
        [JsonProperty("publisher_fee")]
        public string PublisherFee { get; set; }
        [JsonProperty("converted_price")]
        public string ConvertedPrice { get; set; }
        [JsonProperty("converted_fee")]
        public string ConvertedFee { get; set; }
        [JsonProperty("converted_currencyid")]
        public string ConvertedCurrencyid { get; set; }
        [JsonProperty("converted_steam_fee")]
        public string ConvertedSteamFee { get; set; }
        [JsonProperty("converted_publisher_fee")]
        public string ConvertedPublisherFee { get; set; }
        [JsonProperty("converted_fee_per_unit")]
        public string ConvertedFeePerUnit { get; set; }
        [JsonProperty("converted_steam_fee_per_unit")]
        public string ConvertedSteamFeePerUnit { get; set; }
        [JsonProperty("converted_publisher_fee_per_unit")]
        public string ConvertedPublisherFeePerUnit { get; set; }
        public Asset Asset { get; set; }


    }
Mark C.
  • 6,332
  • 4
  • 35
  • 71
1

You're really very close. Your classes will work fine as you've defined them, except you need to change the name of the dictionary property inside your root class from Items to listinginfo to mirror the JSON property name. (Alternatively, you could use a [JsonProperty] attribute to map the Items dictionary to the listinginfo property in the JSON.) After making that change, I would also recommend renaming your root class from listinginfo to something else that makes sense to you, like maybe ListingResponse, but that is not strictly necessary.

After those changes, your root class should look like this:

public class ListingResponse
{
    public Dictionary<string, NewListedItem> listinginfo { get; set; }
}

Or, if you prefer the attribute approach:

public class ListingResponse
{
    [JsonProperty("listinginfo")]
    public Dictionary<string, NewListedItem> Items { get; set; }
}

Then, you should be able to deserialize your JSON into this class and your dictionary will be populated as you expect:

ListingResponse response = JsonConvert.DeserializeObject<ListingResponse>(json);

Fiddle: https://dotnetfiddle.net/V8LsXY

Brian Rogers
  • 125,747
  • 31
  • 299
  • 300
  • Ah, i solved it doing this: JToken root = JObject.Parse(response); JToken testToken = root["listinginfo"]; and then pass the testToken to DeserializeObject. anyway, thank you! – ddacot Jul 09 '16 at 08:21
0
            public class TestClass
            {

                private void Test()
                {
                    var json = "{\r\n    \"637640274112277168\": {\r\n        \"listingid\": \"637640274112277168\",\r\n        \"price\": 50,\r\n        \"fee\": 7,\r\n        \"publisher_fee_app\": 730,\r\n        \"publisher_fee_percent\": \"0.10000000149011612\",\r\n        \"currencyid\": \"2005\",\r\n        \"steam_fee\": 2,\r\n        \"publisher_fee\": 5,\r\n        \"converted_price\": 1,\r\n        \"converted_fee\": 2,\r\n        \"converted_currencyid\": \"2003\",\r\n        \"converted_steam_fee\": 1,\r\n        \"converted_publisher_fee\": 1,\r\n        \"converted_price_per_unit\": 1,\r\n        \"converted_fee_per_unit\": 2,\r\n        \"converted_steam_fee_per_unit\": 1,\r\n        \"converted_publisher_fee_per_unit\": 1,\r\n        \"asset\": {\r\n            \"currency\": 0,\r\n            \"appid\": 730,\r\n            \"contextid\": \"2\",\r\n            \"id\": \"6542776191\",\r\n            \"amount\": \"1\"\r\n        }\r\n    },\r\n    \"194035710805671301\": {\r\n        \"listingid\": \"194035710805671301\",\r\n        \"price\": 0,\r\n        \"fee\": 0,\r\n        \"publisher_fee_app\": 730,\r\n        \"publisher_fee_percent\": \"0.10000000149011612\",\r\n        \"currencyid\": \"2001\",\r\n        \"asset\": {\r\n            \"currency\": 0,\r\n            \"appid\": 730,\r\n            \"contextid\": \"2\",\r\n            \"id\": \"6825071309\",\r\n            \"amount\": \"0\"\r\n        }\r\n    }\r\n    }\r\n\r\n";
                    Dictionary<string, NewListedItem> values = JsonConvert.DeserializeObject<Dictionary<string, NewListedItem>>(json);

                }
            }
            class listinginfo
            {
                public Dictionary<string, List<NewListedItem>> Items;

            }
            class Asset
            {
                public string currency { get; set; }
                public string appid { get; set; }
                public string contextid { get; set; }
                public string id { get; set; }
                public string amount { get; set; }
            }
            class NewListedItem
            {

                public string listingid { get; set; }
                public string price { get; set; }
                public string fee { get; set; }
                public string publisher_fee_app { get; set; }
                public string publisher_fee_percent { get; set; }
                public string steam_fee { get; set; }
                public string publisher_fee { get; set; }
                public string converted_price { get; set; }
                public string converted_fee { get; set; }
                public string converted_currencyid { get; set; }
                public string converted_steam_fee { get; set; }
                public string converted_publisher_fee { get; set; }
                public string converted_fee_per_unit { get; set; }
                public string converted_steam_fee_per_unit { get; set; }
                public string converted_publisher_fee_per_unit { get; set; }
                public Asset asset { get; set; }


            }
Hitesh Thakor
  • 471
  • 2
  • 12
  • add references of Newtonsoft.Json; – Hitesh Thakor Jul 08 '16 at 13:03
  • Install-Package Newtonsoft.Json -Version 6.0.7 – Hitesh Thakor Jul 08 '16 at 13:03
  • You dumped the rest of the JSON response and it works. But having the whole response and running your code, would give: Error converting value True to type 'steambot.NewListedItem'. Path 'success', line 1, position 15. , which from json we see, that it parses the first line too. The ideea, is how do i pass just the listinginfo node, to DeserializeObject ? – ddacot Jul 08 '16 at 13:06