Reputation: 65
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.
Upvotes: 3
Views: 275
Reputation:
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.
Upvotes: 1
Reputation: 8843
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.
Upvotes: 3
Reputation: 13794
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);
Upvotes: 1
Reputation: 5119
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
}]
}
";
Upvotes: 0
Reputation: 263
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.
Upvotes: 1
Reputation: 1864
dict["VisitingTeamFootballRbStats"][0]
gets you the whole Athlete
object.
To access name use .AthleteFirstName
Like so:
dict["VisitingTeamFootballRbStats"][0].AthleteFirstName
Upvotes: 0