简体   繁体   中英

Using JSON in C# deserialized into a dictionary

I deserialized JSON data into a dictionary. This is what my JSON data looks like:

{
    "InputKoffRetStats":true,"InputPenaltyStats":false,
    "VisitingTeamFootballRbStats":
         [{
             "AthleteLastName":"John",
             "AthleteFirstName":"Smith","Number":9,"IsPresent":true
         },
         {
             "AthleteLastName":"Justin",
             "AthleteFirstName":"Brooks","Number":10,"IsPresent":false
         }]
}

And this is how I deserialized the string into a dictionary:

var dict = JsonConvert.DeserializeObject<Dictionary<string, object>>(result);

The problem I have is that I do not know how to get, for example, the first athlete's last name (John).

If I do this:

 Console.WriteLine(dict["InputKoffRetStats"]);

Then I get "True". It works fine.

If I do this:

Console.WriteLine(dict["VisitingTeamFootballRbStats"]);

Then I get the information of both athletes (John and Justin).

How could I use the dictionary to get only the first athletes name? I tried doing the following with no success:

Console.WriteLine(dict["VisitingTeamFootballRbStats"][0]);

Any ideas?

EDIT: I should have mentionned that the json that I showed is just a small portion of the whole json. I just gave it as an example.

A full working example:

public class Athlete
{
    public string AthleteLastName { get; set; }
    public string AthleteFirstName { get; set; }
    public int Number { get; set; }
    public bool IsPresent { get; set; }
}

public class Stat
{
    public bool InputKoffRetStats { get; set; }
    public bool InputPenaltyStats { get; set; }
    public List<Athlete> VisitingTeamFootballRbStats { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var jsonText = "{" +
                        "    \"InputKoffRetStats\":true,\"InputPenaltyStats\":false," +
                        "    \"VisitingTeamFootballRbStats\":" +
                        "         [{" +
                        "             \"AthleteLastName\":\"John\"," +
                        "             \"AthleteFirstName\":\"Smith\",\"Number\":9,\"IsPresent\":true" +
                        "         }," +
                        "         {" +
                        "             \"AthleteLastName\":\"Justin\"," +
                        "             \"AthleteFirstName\":\"Brooks\",\"Number\":10,\"IsPresent\":false" +
                        "         }]" +
                        "}";

        var stat = JsonConvert.DeserializeObject<Stat>(jsonText);

        Console.WriteLine(stat.VisitingTeamFootballRbStats[0].AthleteFirstName);
        Console.ReadKey();
    }
}

PS.: There was an error in the JSON you provided. Once you're using "IsPresent" as a boolean: "IsPresent":true , the next time you're using it as a string: "IsPresent":No (Incorrectly, because No should be "No"). Anyway, I corrected that to be "IsPresent":false .

Update : If you want "JavaScript-like" behavior, so you want to be able to do someObj["someProperty"]["someNestedProperty"] you can do this:

var stat = JsonConvert.DeserializeObject<JObject>(jsonText);

So to get to the first name of the first athlete:

var firstName = stat["VisitingTeamFootballRbStats"][0]["AthleteFirstName"].Value<string>();

That said, I would still create proper classes for all the possible fields in the JSON.

The other way to deserialize is to create a JsonProperty class like below:

public class VisitingTeamFootballRbStats
{
    [JsonProperty("AthleteLastName")]
    public string AthleteLastName{ get; set; }

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

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

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

And then deserialize it like below:

List<VisitingTeamFootballRbStats> visitingTeams = JsonConvert.DeserializeObject<List<VisitingTeamFootballRbStats>>(jsonString["VisitingTeamFootballRbStats"].ToString());

So once you get the list, you can easily get the athletes details as below:

visitingTeams.ElementAt(0).AthleteLastName;

Or you can use linq.

Your code doesn't work because your json object is not a dictionary,it's a custom object here how it's look a serialized dict

{"team1":[{"AthleteLastName":"v2",
"AthleteFirstName":"v1",
"Number":2,
"IsPresent":false}]}

Here a fully working example

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

namespace ConsoleApplication3
{
    class Program
    {
        static void Main(string[] args)
        {
           var team=  "{" +
                       "    \"InputKoffRetStats\":true,\"InputPenaltyStats\":false," +
                       "    \"VisitingTeamFootballRbStats\":" +
                       "         [{" +
                       "             \"AthleteLastName\":\"John\"," +
                       "             \"AthleteFirstName\":\"Smith\",\"Number\":9,\"IsPresent\":true" +
                       "         }," +
                       "         {" +
                       "             \"AthleteLastName\":\"Justin\"," +
                       "             \"AthleteFirstName\":\"Brooks\",\"Number\":10,\"IsPresent\":false" +
                       "         }]" +
                       "}";





            var desTeam = JsonConvert.DeserializeObject<Team>(team);  
            Console.WriteLine(desTeam.VisitingTeamFootballRbStats[0].AthleteFirstName);



        }
    }

    public class Team{
        public bool InputKoffRetStats { get; set; }
        public bool InputPenaltyStats { get; set; }
        public  List<AthleteInfo> VisitingTeamFootballRbStats { get; set; }

    }

    public class AthleteInfo
    {
        public string AthleteLastName { get; set; }
        public string AthleteFirstName { get; set; }
        public int Number { get; set; }
        public bool IsPresent { get; set; }
    }
}

UPDATE

if you are using webapi/wcf you can ask for the data contract otherwise you can use dynamic object for this

Note by using dynamic object you loose the supports of intellisense

Code

//same json string  

 dynamic desDynTeam = JObject.Parse(team);     
             Console.WriteLine(desDynTeam.VisitingTeamFootballRbStats[0].AthleteLastName); 

The VisitingTeamFootballRbStats array gets pretty long or there are other fields in the outer in the JSON. If the JSON is known and not going to change, I would still go with adding proper classes to my .NET project and deserialize into that.

dict["VisitingTeamFootballRbStats"][0] gets you the whole Athlete object.

To access name use .AthleteFirstName

Like so:

dict["VisitingTeamFootballRbStats"][0].AthleteFirstName

Have you checked out dynamics in .NET? Here is a simple console app using Newtonsoft.Json that shows how you can access those properties on your JSON object:

static void Main(string[] args)
{
    dynamic dObject = JObject.Parse(json);

    Console.WriteLine(dObject.VisitingTeamFootballRbStats[0].AthleteLastName); 
    //Prints "John"

    Console.ReadLine();
}

private static string json = @"
    {
        'InputKoffRetStats':true,'InputPenaltyStats':false,
        'VisitingTeamFootballRbStats':
        [{
            'AthleteLastName':'John',
            'AthleteFirstName':'Smith','Number':9,'IsPresent':true
        },
        {
            'AthleteLastName':'Justin',
            'AthleteFirstName':'Brooks','Number':10,'IsPresent':false
        }]
    }
    ";

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