How to Deserialize JSON object with arrays with objects using JSON.NET - c#

I have this JSON file which i want to Deserialize.
{
"agencies":[
{
"id":44,
"name":"National Aeronautics and Space Administration",
"countryCode":"USA",
"abbrev":"NASA",
"type":1,"infoURL":"http:\/\/www.nasa.gov",
"wikiURL":"http:\/\/en.wikipedia.org\/wiki\/National_Aeronautics_and_Space_Administration",
"infoURLs":[
"http:\/\/www.nasa.gov"
]
}
],
"total":0,
"count":1,
"offset":0
}
I currenly have this code for getting the JSON and trying to deserialize it.
RestClient client = new RestClient("https://launchlibrary.net/1.2/agency");
RestRequest request = new RestRequest("NASA",Method.GET);
var results = client.Execute(request).Content;
MessageBox.Show(JsonConvert.DeserializeObject(results).ToString());
// Deserialize
RootObject rootObject = JsonConvert.DeserializeObject<RootObject>(results);
MessageBox.Show(rootObject.agencies.Count.ToString());
And this
public class Agency
{
public int id { get; set; }
public string name { get; set; }
public string countryCode { get; set; }
public string abbrev { get; set; }
public int type { get; set; }
public string infoURL { get; set; }
public string wikiURL { get; set; }
public List<string> infoURLs { get; set; }
}
public class RootObject
{
public List<Agency> agencies { get; set; }
public int total { get; set; }
public int count { get; set; }
public int offset { get; set; }
}
I can easily get to the things just inside the object such as total and count but not the array agencies.
How do I do this?
I'm only interested in the data inside the agencies array and not the total, count and offset

Related

Deserialize nested JSON, C# [duplicate]

This question already has an answer here:
Deserialize Nested JSON
(1 answer)
Closed 1 year ago.
I need to deserialize some JSON with this format:
{
"message": {
"header": {
"status_code": 200,
"execute_time": 0.29062294960022,
"available": 10000
},
"body": {
"track_list": [
{
"track": {
"track_id": 45085706,
"track_name": "Love Overdose (Deboa & Hannah Holland Remix)",
"primary_genres": {
"music_genre_list": [
{
"music_genre": {
"music_genre_name": "Dance"
}
}
]
}
}
}
]
}
}
}
I have these classes which I got from online generator, so I assume they are ok.
public class Header
{
public int status_code { get; set; }
public double execute_time { get; set; }
public int available { get; set; }
}
public class MusicGenre
{
public int music_genre_id { get; set; }
public int music_genre_parent_id { get; set; }
public string music_genre_name { get; set; }
public string music_genre_name_extended { get; set; }
public string music_genre_vanity { get; set; }
}
public class MusicGenreList
{
public MusicGenre music_genre { get; set; }
}
public class PrimaryGenres
{
public List<MusicGenreList> music_genre_list { get; set; }
}
public class Track
{
public int track_id { get; set; }
public string track_name { get; set; }
public List<object> track_name_translation_list { get; set; }
public int track_rating { get; set; }
public int commontrack_id { get; set; }
public int instrumental { get; set; }
public int #explicit { get; set; }
public int has_lyrics { get; set; }
public int has_subtitles { get; set; }
public int has_richsync { get; set; }
public int num_favourite { get; set; }
public int album_id { get; set; }
public string album_name { get; set; }
public int artist_id { get; set; }
public string artist_name { get; set; }
public string track_share_url { get; set; }
public string track_edit_url { get; set; }
public int restricted { get; set; }
public DateTime updated_time { get; set; }
public PrimaryGenres primary_genres { get; set; }
}
public class TrackList
{
public Track track { get; set; }
}
public class Body
{
public List<TrackList> TrackList { get; set; }
}
public class Message
{
public Header header { get; set; }
public Body body { get; set; }
}
public class Root
{
public Message message { get; set; }
}
I tried to deserialize the JSON with this code:
using (StreamReader r = new StreamReader(#"c:\users\xxxx\desktop\1.json"))
{
string json = r.ReadToEnd();
var tracks = JsonConvert.DeserializeObject<Track>(json);
}
but I got nothing. I'm new to this; made it with simpler JSON, but I can't figure out how to do it with this code. I want to print a list with just the song names.
If anyone can help me I would appreciate it!
There are a couple of problems here:
In your Body class, the TrackList property does not match the JSON. The corresponding property in the JSON is called track_list. The class properties must either exactly match the JSON (ignoring case) or else you need to use a [JsonProperty] attribute on the property to indicate what the JSON name will be. For example:
public class Body
{
[JsonProperty("track_list")]
public List<TrackList> TrackList { get; set; }
}
You are attempting to deserialize into the Track class, but you should be deserializing to Root since that represents the root of the JSON.
var root = JsonConvert.DeserializeObject<Root>(json);
Once you have deserialized to Root you can "drill down" to print out the tracks.
foreach (var item in root.message.body.TrackList)
{
Console.WriteLine(item.track.track_name);
}
Fiddle: https://dotnetfiddle.net/JnljGU

Need assign List object parsed from JSON file to a object property

I trying to build Magic The Gathering card viewer and getting data from json. I have created json file, then copy all and paste special to my class to generate a model. In constructor using json parser I parsed object fine, but when I try to assign to that object property, so I can make method retrieve all cards. But when I trying to do that it says that I can't implicitly assign. I try to assign Cards = cardsCollection; that where it throws an error.
namespace MTGArena
{
public class Cards
{
public class Rootobject
{
static Rootobject()
{
using (StreamReader file = new StreamReader("cards.json"))
{
string json = file.ReadToEnd();
Rootobject cardsCollection = JsonConvert.DeserializeObject<Rootobject>(json);
Cards = cardsCollection;
}
}
public static List<Card> Cards { get; set; }
public static List<Card> GetCards()
{
return Cards;
}
}
}
public class Card
{
public string name { get; set; }
public string set { get; set; }
public Images images { get; set; }
public string type { get; set; }
public string[] cost { get; set; }
public int cmc { get; set; }
public string rarity { get; set; }
public string cid { get; set; }
public int?[] frame { get; set; }
public string artist { get; set; }
public string dfc { get; set; }
public bool collectible { get; set; }
public bool craftable { get; set; }
public int dfcId { get; set; }
public int rank { get; set; }
public string grpId { get; set; }
}
public class Images
{
public string small { get; set; }
public string normal { get; set; }
public string large { get; set; }
public string art_crop { get; set; }
}
}
Change the line:
Rootobject cardsCollection = JsonConvert.DeserializeObject<Rootobject>(json);
for:
var cardsCollection = JsonConvert.DeserializeObject<List<Card>>(json);
You need to use below syntax
IList<Card> cards = cardsCollection;
dont create empty Cards class. It has no use

How to parse this http response in C#

How would I parse this response using C#?
[
{
"date":"2016-10-01",
"stats":[
{
"type":"subuser",
"name":"coolguy#yahoo.com",
"metrics":{
"blocks":23,
"bounce_drops":164,
"bounces":19,
"clicks":0,
"deferred":412,
"delivered":3435,
"invalid_emails":27,
"opens":0,
"processed":3481,
"requests":3675,
"spam_report_drops":3,
"spam_reports":0,
"unique_clicks":0,
"unique_opens":0,
"unsubscribe_drops":0,
"unsubscribes":0
}
}
]
},
{
"date":"2016-10-02",
"stats":[
{
"type":"subuser",
"name":"coolguy#yahoo.com",
"metrics":{
"blocks":0,
"bounce_drops":0,
"bounces":0,
"clicks":0,
"deferred":95,
"delivered":0,
"invalid_emails":0,
"opens":0,
"processed":0,
"requests":0,
"spam_report_drops":0,
"spam_reports":0,
"unique_clicks":0,
"unique_opens":0,
"unsubscribe_drops":0,
"unsubscribes":0
}
}
]
}
]
Using JsonConvert deserialize it to dynamic as below or create a matching class structure and deserialize it to that.
using Newtonsoft.Json;
.....
string json = File.ReadAllText("data.txt");
var deserializedData = JsonConvert.DeserializeObject<dynamic>(json);
Using json2csharp your classes should look like:
public class Metrics
{
public int blocks { get; set; }
public int bounce_drops { get; set; }
public int bounces { get; set; }
public int clicks { get; set; }
public int deferred { get; set; }
public int delivered { get; set; }
public int invalid_emails { get; set; }
public int opens { get; set; }
public int processed { get; set; }
public int requests { get; set; }
public int spam_report_drops { get; set; }
public int spam_reports { get; set; }
public int unique_clicks { get; set; }
public int unique_opens { get; set; }
public int unsubscribe_drops { get; set; }
public int unsubscribes { get; set; }
}
public class Stat
{
public string type { get; set; }
public string name { get; set; }
public Metrics metrics { get; set; }
}
public class RootObject
{
public string date { get; set; }
public List<Stat> stats { get; set; }
}
These generated classes can be improved - for example not storing the date in a string but a DateTime
string json = File.ReadAllText("data.txt");
RootObject deserializedData = JsonConvert.DeserializeObject<RootObject>(json);

Linq transformation help needed

I've got a List of this object:
public class WebinarAttendeesList {
public int wa_id { get; set; }
public int PID { get; set; }
public string FullName { get; set; }
public string Email { get; set; }
public string JoinTime { get; set; }
public string TimeInSession { get; set; }
public string LeaveTime { get; set; }
public int FirstPollCount { get; set; }
public int SecondPollCount { get; set; }
public int AttendedWebinar { get; set; }
public int Makeup { get; set; }
public string Comments { get; set; }
public string RegistrantKey { get; set; }
public string webinarKey { get; set; }
}
I'm using this Linq code:
var webinars = new
{
Webinars = r.GroupBy(x => new { x.PID, x.FullName }).
Select(y => new
{
PID = y.Key.PID,
FullName = y.Key.FullName,
AffReceived = 0,
Attendances = y.Select(z => new
{
WebinarKey = z.webinarKey,
RegistrantKey = z.RegistrantKey,
TimeInSession = z.TimeInSession,
FirstPollCount = z.FirstPollCount,
SecondPollCount = z.SecondPollCount,
AttendedWebinar = z.AttendedWebinar
})
})
};
string json = JsonConvert.SerializeObject(webinars);
to transform the List to JSON. But, I think I'd rather
have it transformed into a List<FinalWebinarAttendeesList> (see below
definition). The JSON that it produces looks correct and passes lint.
When I try to do this:
List<FinalWebinarAttendeesList> fl = JsonConvert.DeserializeObject<List<FinalWebinarAttendeesList>>(json);
I get an error:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type
'System.Collections.Generic.List`1[WebinarProject.Models.FinalWebinarAttendeesList]'
because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or
change the deserialized type so that it is a normal .NET type (e.g. not a
primitive type like integer, not a collection type like an array or List<T>)
that can be deserialized from a JSON object. JsonObjectAttribute can also be
added to the type to force it to deserialize from a JSON object. Path
'Webinars', line 1, position 12.
How can I either transform this directly into the object I want, or be able to deserialize it into the object I want?
FinalWebinarAttendeesList definition:
public class FinalWebinarAttendeesList
{
public FinalWebinar Webinars {get; set; }
}
public class FinalWebinar
{
public int PtID { get; set; }
public string FullName { get; set; }
public int AffReceived { get; set; }
public List<FinalWebinarAttendee> Attendances { get; set; }
}
public class FinalWebinarAttendee
{
public string RegistrantKey { get; set; }
public string TimeInSession { get; set; }
public int FirstPollCount { get; set; }
public int SecondPollCount { get; set; }
public int AttendedWebinar { get; set; }
}
I created a json sample output using random data and and I found that you are trying to deserialize the json with the wrong object.
Json output:
{"Webinars":[{"PID":453,"FullName":"jdis","Attendances":[{"WebinarKey":"kdnsaod","RegistrantKey":"udhaso","TimeInSession":"hdija","FirstPollCount":45,"SecondPollCount":45,"AttendedWebinar":0}]}]}
The object has de following structure:
public class Attendance
{
public string WebinarKey { get; set; }
public string RegistrantKey { get; set; }
public string TimeInSession { get; set; }
public int FirstPollCount { get; set; }
public int SecondPollCount { get; set; }
public int AttendedWebinar { get; set; }
}
public class Webinar
{
public int PID { get; set; }
public string FullName { get; set; }
public List<Attendance> Attendances { get; set; }
}
public class RootObject
{
public List<Webinar> Webinars { get; set; }
}
And for Deserializing the object:
var result = JsonConvert.DeserializeObject<RootObject>(json);
You created only one Webinar instance, but you are trying to deserialize a list of Webinars. Try:
FinalWebinarAttendeesList fl = JsonConvert.DeserializeObject<FinalWebinarAttendeesList>(json);

What is the right C# structure to deserialize this json into?

I am getting json back from an http and I am trying to deserialized it into a C# object and it keeps coming back as null so my guess is that my data structure is off. Here is my code:
results = httpClient.GetStringAsync(url).Result;
var restResponse = new RestSharp.RestResponse();
restResponse.Content = results;
var deserializer = new JsonDeserializer();
var page = _deserializer.Deserialize<Tree>(restResponse);
Here is the Json:
{
"page":{
"results":[
{
"id":"144111690",
"type":"page",
"status":"current",
"title":"Title 1"
},
{
"id":"157540319",
"type":"page",
"status":"current",
"title":"Title 2"
},
{
"id":"144082624",
"type":"page",
"status":"current",
"title":"Title 3"
}
],
"start":0,
"limit":25,
"size":14
}
}
and Here are my C# objects:
public class Tree
{
public Results page { get; set; }
}
public class Results
{
public ResultDetails results { get; set; }
}
public class ResultDetails
{
public List<PageInfo> Pages { get; set; }
}
public class PageInfo
{
public long id { get; set; }
public string type { get; set; }
public string status { get; set; }
public string title { get; set; }
}
Can anyone advise on what is not "lining up" here?
Why don't you directly create class structure by using Visual studio ..that will give you class structure matching with your json.
you can check here how to generate : Visual Studio Generate Class From JSON or XML
Copy you json >> visual studio Edit menu > Paste Special >> Paste Json as class
This will work:
public class Tree
{
public Page page { get; set; }
}
public class Page
{
public List<Result> results { get; set; }
public int start { get; set; }
public int limit { get; set; }
public int size { get; set; }
}
public class Result
{
public string id { get; set; }
public string type { get; set; }
public string status { get; set; }
public string title { get; set; }
}
results is an array in JSON, but you defined it as an object (ResultDetails)
This might do the trick for you
public class Rootobject
{
[JsonProperty("page")]
public Page page { get; set; }
}
public class Page
{
[JsonProperty("results")]
public Result[] results { get; set; }
[JsonProperty("start")]
public int start { get; set; }
[JsonProperty("limit")]
public int limit { get; set; }
[JsonProperty("size")]
public int size { get; set; }
}
public class Result
{
[JsonProperty("id")]
public string id { get; set; }
[JsonProperty("type")]
public string type { get; set; }
[JsonProperty("status")]
public string status { get; set; }
[JsonProperty("title")]
public string title { get; set; }
}
And the implementation should be
results = httpClient.GetStringAsync(url).Result;
var restResponse = new RestSharp.RestResponse();
restResponse.Content = results;
var deserializer = new JsonDeserializer();
var page = _deserializer.Deserialize<Rootobject>(restResponse);

Categories

Resources