2

I am trying to search this Json Code to find statistics:

{
    "summonerId": 32033681,
    "modifyDate": 1403658807000,
    "champions": [{
        "id": 40,
        "stats": {
            "totalSessionsPlayed": 1,
            "totalSessionsLost": 0,
            "totalSessionsWon": 1,
            "totalChampionKills": 1,
            "totalDamageDealt": 27006,
            "totalDamageTaken": 9924,
            "mostChampionKillsPerSession": 1,
            "totalMinionKills": 17,
            "totalDoubleKills": 0,
            "totalTripleKills": 0,
            "totalQuadraKills": 0,
            "totalPentaKills": 0,
            "totalUnrealKills": 0,
            "totalDeathsPerSession": 2,
            "totalGoldEarned": 8383,
            "mostSpellsCast": 0,
            "totalTurretsKilled": 2,
            "totalPhysicalDamageDealt": 8957,
            "totalMagicDamageDealt": 18049,
            "totalFirstBlood": 0,
            "totalAssists": 13,
            "maxChampionsKilled": 1,
            "maxNumDeaths": 2
        }
    },
    {
        "id": 36,
        "stats": {
            "totalSessionsPlayed": 1,
            "totalSessionsLost": 1,
            "totalSessionsWon": 0,
            "totalChampionKills": 0,
            "totalDamageDealt": 14267,
            "totalDamageTaken": 7649,
            "mostChampionKillsPerSession": 0,
            "totalMinionKills": 33,
            "totalDoubleKills": 0,
            "totalTripleKills": 0,
            "totalQuadraKills": 0,
            "totalPentaKills": 0,
            "totalUnrealKills": 0,
            "totalDeathsPerSession": 5,
            "totalGoldEarned": 3258,
            "mostSpellsCast": 0,
            "totalTurretsKilled": 0,
            "totalPhysicalDamageDealt": 4992,
            "totalMagicDamageDealt": 9165,
            "totalFirstBlood": 0,
            "totalAssists": 0,
            "maxChampionsKilled": 0,
            "maxNumDeaths": 5
        }
    }]
}

In the following example, I want to be able search for totalSessionsWon for id 36. I tried accessing the data how I have been accessing data from other JSON files but it doesn't allow me to specify the id of the champion I am searching for:

string jsonInput = new WebClient().DownloadString(@usableurl); //Reads the JSON from the API
string usableJson = @"JObject.Parse(jsonInput)"; //converts the JSON from the API to a usable form
var usableJson["champions"]["stats"]["totalSessionWon"];

Is there a way that I could choose a specific statistic based on the id before it?

I'm new to using both JSON and C#, so your help is especially appreciated!

Jim Hewitt
  • 1,726
  • 4
  • 24
  • 26
Dan
  • 173
  • 2
  • 9
  • The structure of your JSON looks fine. It looks like you need to learn more about JSON and how to read/write it with C#. There's plenty of tutorials found on the subject if you search the web for it. If you are just looking for tutorials, they're [off topic](http://stackoverflow.com/help/on-topic) on Stack Overflow. However, if you post code of your current attempt, we could help out where you're going wrong at accessing the desired data. – Adrian Sanguineti Nov 24 '16 at 02:16
  • 1
    @Plutonix What did that possum ever do to you? – Asad Saeeduddin Nov 24 '16 at 02:17
  • 2
    @AsadSaeeduddin She ignored all the highly rated links to the right under **Related**. ;) – Ňɏssa Pøngjǣrdenlarp Nov 24 '16 at 02:19
  • Amazing how a question can change so rapidly ... like *"Is there a way I can move the stats to be accessible underneath the id?"* was edited to *"Is there a way that I could choose a specific statistic based on the id before it?"* ... be careful on your next question @Dan :-) – Jim Nov 24 '16 at 03:39

2 Answers2

4

If Newtonsoft.Json; is new for you than you can have a look at how to install Newtonsoft now once the installation is done i would love to tell you that XML, JSON are an open-standard format that uses human-readable text to transmit data objects consisting of attribute–value pairs. The fetching of the data from this kind of strings would be as easier as database.

For fetching the data from the json string with ease first we need to make the object of the json string which shows the heirarchy and thus we need to see how our data or json string looks like. So if you see the top most level of the heirarchy contains summonerId, modifyDate and champions Inside champions there could be n number of champion details so we created the list of champion as champions

now one level down of the heirarchy you can see the champion id and his stats so stats would be one more class to create about the champion. so your class would look like

public class Rootobject
{
    public int summonerId { get; set; }
    public long modifyDate { get; set; }
    public List<Champion> champions { get; set; }
}

public class Champion
{
    public int id { get; set; }
    public Stats stats { get; set; }
}

public class Stats
{
    public int totalSessionsPlayed { get; set; }
    public int totalSessionsLost { get; set; }
    public int totalSessionsWon { get; set; }
    public int totalChampionKills { get; set; }
    public int totalDamageDealt { get; set; }
    public int totalDamageTaken { get; set; }
    public int mostChampionKillsPerSession { get; set; }
    public int totalMinionKills { get; set; }
    public int totalDoubleKills { get; set; }
    public int totalTripleKills { get; set; }
    public int totalQuadraKills { get; set; }
    public int totalPentaKills { get; set; }
    public int totalUnrealKills { get; set; }
    public int totalDeathsPerSession { get; set; }
    public int totalGoldEarned { get; set; }
    public int mostSpellsCast { get; set; }
    public int totalTurretsKilled { get; set; }
    public int totalPhysicalDamageDealt { get; set; }
    public int totalMagicDamageDealt { get; set; }
    public int totalFirstBlood { get; set; }
    public int totalAssists { get; set; }
    public int maxChampionsKilled { get; set; }
    public int maxNumDeaths { get; set; }
}

Now since we already got the structure we need to Deserialize the string to the object of our type that is Rootobject. That will convert that normal json string to fill in the objects. Now just fetch the details like eating a cake.

using Newtonsoft.Json;

Rootobject rt = JsonConvert.DeserializeObject<Rootobject>(jsonstr);
if(rt.champions[1].id == 36)
{
    Console.WriteLine(rt.champions[1].stats.totalSessionsWon);
}
Community
  • 1
  • 1
Mohit S
  • 13,723
  • 6
  • 34
  • 69
  • Considering the author of the question is new to JSON and C#, it might be better to include some explanation of how this code solves what the user wants rather than just providing the solution. (In other words explain what's going on in the code) – Adrian Sanguineti Nov 24 '16 at 02:30
  • 1
    Hope @Adrian this explanation is enough. :) – Mohit S Nov 24 '16 at 02:47
  • Yes I think you have made a decent attempt at explaining how this solves the question. – Adrian Sanguineti Nov 24 '16 at 02:50
2

As the question's author was attempting to use JObject to query their JSON object, I thought I would give a solution using the same.

JObject is for querying JSON with Linq. Linq is a semi-advanced subject for new C# programmers to get their head around but in short, is a specialised query language for retrieving data from a data source. The method outlined in Mohit Shrivastrava's answer is much easier for new programmers to get their head around.

//converts the JSON from the API to a usable form
JObject usableJson = JObject.Parse(json); 

// retrieve champion objects
JToken champions = usableJson["champions"];

// retrieve the champion desired object using the Linq FirstOrDefault method. 
// This method will return the first object that matches the given query,
// or return null if it does not find a match.
JToken champion = champions.FirstOrDefault(c=> (int)c["id"] == 36);

if (champion != null)
{
    // retrieve the stats object
    JToken stats = champion["stats"];

    // read the totalSessionsWon field from the object.
    int totalSessionsWon = (int) stats["totalSessionsWon"];
}
Adrian Sanguineti
  • 2,455
  • 1
  • 27
  • 29