0

I need to parse the JSON response that is linked at the bottom of this post. I have tried several very standard methods to parse this JSON but I believe it is not legal JSON. Does anyone have any solutions that would allow me to parse this JSON?

Response in question: http://steamcommunity.com/id/Mambocsgoshack/inventory/json/730/2/

Snippet of response, if you want to see that actual response it isn't hard just click the link. Some can't do that, I'm told.

{"success":true,"rgInventory":{"1482735510":{"id":"1482735510","classid":"469449975","instanceid":"0","amount":"1","pos":1},"1468698711":{"id":"1468698711","classid":"619638799","instanceid":"0","amount":"1","pos":2},"1468698710":{"id":"1468698710","classid":"666312349","instanceid":"0","amount":"1","pos":3},"1468698709":{"id":"1468698709","classid":"666310610","instanceid":"0","amount":"1","pos":4},"1468698708":{"id":"1468698708","classid":"614052764","instanceid":"0","amount":"1","pos":5},"1462270322":{"id":"1462270322","classid":"520025252","instanceid":"0","amount":"1","pos":6},"1459818809":{"id":"1459818809","classid":"638240019","instanceid":"0","amount":"1","pos":7},"1450750270":{"id":"1450750270","classid":"621559757","instanceid":"188530139","amount":"1","pos":8},"1391297747":{"id":"1391297747","classid":"384801319","instanceid":"0","amount":"1","pos":9},"1370560151":{"id":"1370560151","classid":"469445126","instanceid":"0","amount":"1","pos":10},"1314553100":{"id":"1314553100","classid":"638240019","instanceid":"0","amount":"1","pos":11},"1305163655":{"id":"1305163655","classid":"469431148","instanceid":"0","amount":"1","pos":12},"1304896559":{"id":"1304896559","classid":"310778121","instanceid":"0","amount":"1","pos":13},"1304062628":{"id":"1304062628","classid":"638240019","instanceid":"0","amount":"1","pos":14},"1214784536":{"id":"1214784536","classid":"575589550","instanceid":"519977179","amount":"1","pos":15},"1201208194":{"id":"1201208194","classid":"360467265","instanceid":"188530670","amount":"1","pos":16},"1189828757":{"id":"1189828757","classid":"519982340","instanceid":"519977179","amount":"1","pos":17},"1103736871":{"id":"1103736871","classid":"638237282","instanceid":"565664004","amount":"1","pos":18},"1103736870":{"id":"1103736870","classid":"638237283","instanceid":"565664004","amount":"1","pos":19},"1103736869":{"id":"1103736869","classid":"742266438","instanceid":"674552754","amount":"1","pos":20},"957595359":{"id":"957595359","classid":"527649910","instanceid":"188530170","amount":"1","pos":21},"814442137":{"id":"814442137","classid":"527678066","instanceid":"188530382","amount":"1","pos":22},"623936007":{"id":"623936007","classid":"469452066","instanceid":"0","amount":"1","pos":23},"616381102":{"id":"616381102","classid":"519985137","instanceid":"519977179","amount":"1","pos":24},"612997861":{"id":"612997861","classid":"616333150","instanceid":"571452803","amount":"1","pos":25},"603041123":{"id":"603041123","classid":"519980785","instanceid":"519977179","amount":"1","pos":26}},"rgCurrency":[],"rgDescriptions":{"469449975_0":{"appid":"730","classid":"469449975","instanceid":"0","icon_url":"fWFc82js0fmoRAP-qOIPu5THSWqfSmTELLqcUywGkijVjZYMUrsm1j-9xgEObwgfEh_nvjlWhNzZCveCDfIBj98xqodQ2CZknz5oM7bgZghmfzvDE61HY-Yy_QbpNis77893GtbmoLpffljq4tCXNLN9ZY0fSZPVCaWPZQ_5v0tshKIJK5KBqSjs2i73ejBdAx_EB8I","icon_url_large":"fWFc82js0fmoRAP-qOIPu5THSWqfSmTELLqcUywGkijVjZYMUrsm1j-9xgEObwgfEh_nvjlWhNzZCveCDfIBj98xqodQ2CZknz5oM7bgZghmfzvDE61HY-Yy_QbpNis77893a9u35bwDZ13vs9PPNOQpZoodGMOBD6PVMFr4uRgxg6dZepXdpCm72SrhM2wJXBD1ujVT-Ntzxu8","icon_drag_url":"","name":"SG 553 | Army Sheen","market_hash_name":"SG 553 | Army Sheen (Factory New)","market_name":"SG 553 | Army Sheen (Factory New)","name_color":"D2D2D2","background_color":"","type":"Consumer Grade Rifle","tradable":1,"marketable":1,"commodity":0,"descriptions":[{"type":"html","value":"Exterior: Factory New"},{"type":"html","value":" "},{"type":"html","value":"The terrorist-exclusive SG553 is a premium scoped alternative to the AK47 for effective long-range engagement. It has been covered in a metallic foil stamped with a camouflage pattern."},{"type":"html","value":" "},{"type":"html","value":"The Bank Collection","color":"9da1a9","app_data":{"def_index":"65535","is_itemset_name":1}},{"type":"html","value":" "}],"actions":[{"name":"Inspect in Game...","link":"steam:\/\/rungame\/730\/76561202255233023\/+csgo_econ_action_preview%20S%owner_steamid%A%assetid%D2486209296654018845"}],"market_actions":[{"name":"Inspect in Game...","link":"steam:\/\/rungame\/730\/76561202255233023\/+csgo_econ_action_preview%20M%listingid%A%assetid%D2486209296654018845"}],"tags":[{"internal_name":"CSGO_Type_Rifle","name":"Rifle","category":"Type","category_name":"Type"},{"internal_name":"weapon_sg556","name":"SG 553","category":"Weapon","category_name":"Weapon"},{"internal_name":"set_bank","name":"The Bank Collection","category":"ItemSet","category_name":"Collection"},{"internal_name":"normal","name":"Normal","category":"Quality","category_name":"Category"},{"internal_name":"Rarity_Common_Weapon","name":"Consumer Grade","category":"Rarity","color":"b0c3d9","category_name":"Quality"},{"internal_name":"WearCategory0","name":"Factory New","category":"Exterior","category_name":"Exterior"}]},"619638799_0":{"appid":"730","classid

Alright, so the basics I have tried:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Newtonsoft.Json;
using SteamKit2;
using System.Net;

namespace SteamTrade
{
    public class CSGOInventory
    {
        public static CSGOInventory FetchInventory(string steamId)
        {
            WebClient client = new WebClient();
            var url = "http://steamcommunity.com/profiles/" + steamId + "/inventory/json/730/2/";
            string response =  client.DownloadString(url);
            InventoryResponse result = Newtonsoft.Json.JsonConvert.DeserializeObject<InventoryResponse>(response);
            return new CSGOInventory(result.result);
        }

        public Item[] Items { get; set; }

        protected CSGOInventory(InventoryResult apiInventory)
        {
            Items = apiInventory.items;
        }

        public Item GetItem(int id)
        {
            return (Items == null ? null : Items.FirstOrDefault(item => item.instanceid == id));
        }

        public List<Item> GetItemsByDefindex(int defindex)
        {
            return Items.Where(item => item.def_index == defindex).ToList();
        }

        public class Item
        {
            public int AppId = 730;
            public long ContextId = 2;

            [JsonProperty("instanceid")]
            public int instanceid { get; set; }

            [JsonProperty("market_name")]
            public string market_name { get; set; }

            [JsonProperty("def_index")]
            public int def_index { get; set; }

        }

        protected class InventoryResult
        {
            public Item[] items { get; set; }
        }

        protected class InventoryResponse
        {
            public InventoryResult result;
        }

    }
}

Error I get:

Object reference not set to an instance of an object.

I get the error on this line:

protected CSGOInventory(InventoryResult apiInventory)
    {
        Items = apiInventory.items;
    }

I think that I need to serialize it to a dictionary but I am not sure how to implement this into my code. Could anyone suggest a suitable implementation in this situation?

  • That's perfectly valid JSON. Just use the JSON.Net Nuget package. – Brandon Feb 03 '15 at 20:39
  • json2csharp cannot make any sense of it and JSON.net cannot parse it either. It could be my object class, but going my json2csharp this is not a regular/normal response.EDIT: other json parser are saying there are errors too. – Keillen Hayes Feb 03 '15 at 20:42
  • @KeillenHayes, Please see the FAQ on how to ask a good question http://stackoverflow.com/help/how-to-ask. You may have tried stuff, but you need to be more explicit as to exactly what you tried, why it failed, what error message you got, etc. – Brandon Feb 03 '15 at 20:49
  • Make sure you specify *what line* an error occurs on. But that error means you are trying to use an object that is `null`. – crashmstr Feb 03 '15 at 20:54
  • @KeillenHayes did you create this json, I think the issue you cannot name properties with digits – meda Feb 03 '15 at 20:56
  • No the JSON is retrieved from the Steam website. – Keillen Hayes Feb 03 '15 at 20:58
  • @KeillenHayes Answer is simple. You can not use for ex, `619638799_0` as a variable name in c#. So you should declare them as `Dictionary`, Search SO, I remember many asnwers similar to this. I would post a complete answer If you had been more polite, as for someone in need – EZI Feb 03 '15 at 21:01
  • http://json2csharp.com/# reports that some parts are invalid. http://jsonviewer.stack.hu/ is a nice tool for visualization. – Keith Payne Feb 03 '15 at 21:02
  • @EZI please consider that maybe your first post was slightly rude. You said try something before asking here, suggesting I had not - even though I said that I had in the post. I was rude in response to your attitude. Consider that. – Keillen Hayes Feb 03 '15 at 21:04
  • @KeillenHayes Please include a snippet of the JSON in your post (enough to be representative of the structure to be parsed). It's not enough to just provide a link to it in the question, as the question should be self contained. – mason Feb 03 '15 at 21:05
  • @EZI sorry your honor. I now respect your status as a deity since you know the answer to this problem and I don't. May you in your endless grace please post the answer to the question. EDIT: You just answered the question, so it clearly isn't too broad. Also, why does everyone have to stick to the rules religiously here, it is clear what I am asking and you clearly know the answer, so why not be helpful and answer it?... – Keillen Hayes Feb 03 '15 at 21:07
  • @mason Question is now self-contained. It is also not too broad seeing as it is specific, and thus, not broad... – Keillen Hayes Feb 03 '15 at 21:12
  • @KeillenHayes I did not vote to close as too broad, I voted that the question didn't contain everything it needed (the close message only shows what the majority of people voted for, the close reason of the minority is ignored but their vote still counts). But now I believe it does contain enough info and I will vote to re-open. – mason Feb 03 '15 at 21:13
  • So, I can only assume that the majority did not read the question. That's a shame. – Keillen Hayes Feb 03 '15 at 21:14
  • When I voted, it was *too broad*, Now a +1 for reopen (BTW: `...clearly know the answer` I don't like to help people who don't show any effort by themselves (Your question was like this in its early form) ) – EZI Feb 03 '15 at 21:16
  • Ok, and I'm unsure what you meant when you said to search for other responses. I'm not sure what to look for. – Keillen Hayes Feb 03 '15 at 21:20
  • @KeillenHayes see for ex http://stackoverflow.com/questions/24536533/how-can-i-parse-a-json-string-that-would-cause-illegal-c-sharp-identifiers – EZI Feb 03 '15 at 21:21
  • @EZI I still don't see how to apply this to my situation i.e. I thought the DeserializeObject returns an object, so how can I convert a dictionary to, in my case, an InventoryResult – Keillen Hayes Feb 03 '15 at 22:00
  • Ok, so basically now my issue is the implementation of what you have suggested. Also, do I need every JsonProperty to be specified or if I omit some will it just skip over them? – Keillen Hayes Feb 03 '15 at 22:56

1 Answers1

-1

I just saved the json from that website into a file, added it as a resource to a console app and the following code worked fine

static void Main(string[] args)
{
    string json = Properties.Resources.json;
    var deserialized = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
}

You either have the data saved/retrieved incorrectly or using a sub-standard JSON library. Try NewtonSoft JSON

Having looked at the code in your updated question I would guess the data is incorrect because you are using a different URL.

http://steamcommunity.com/profiles/" + steamId + "/inventory/json/730/2/ http://steamcommunity.com/id/Mambocsgoshack/inventory/json/730/2/

Peter Morris
  • 20,174
  • 9
  • 81
  • 146
  • 1
    `and the following code worked fine` It would work for **every** valid json (and the json in question is valid). How does this post answer the question? – EZI Feb 03 '15 at 20:51
  • Updated the question with what I tried and the error I got. – Keillen Hayes Feb 03 '15 at 20:52
  • It answers the question by proving both the JSON is valid and it is possible to parse it in, therefore either the data is saved/retrieved incorrectly or a rubbish library is being used. That is how it answers the question. – Peter Morris Feb 03 '15 at 22:30
  • In what way is the exact code to achieve the desired goal *not* an answer to the question? – Peter Morris Feb 03 '15 at 22:37
  • @PeterMorris the comments under my original question I think solve the issue in theory, but I can't implement it. Also, the /id link and /profiles link to respond with the same thing but you have to put a different link in afterwards. – Keillen Hayes Feb 03 '15 at 22:49
  • the /profiles path returns HTML, the /id path returns JSON, that's your problem! – Peter Morris Feb 03 '15 at 23:26
  • When using a browser it redirects me. The issue is, not everyone has a /id path so I need to use the /profiles link. How could I get the redirected content? – Keillen Hayes Feb 03 '15 at 23:51
  • Perhaps you could get the /id/ and if that fails (not found / redirect, / whatever) then get the /profiles/ content. But if the /profiles/ content is always html then you'll need to parse it for the data you need. HtmlAgilityPack is good for parsing HTML http://htmlagilitypack.codeplex.com/ – Peter Morris Feb 04 '15 at 10:29