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
Related
This question already has answers here:
How can I parse a JSON string that would cause illegal C# identifiers?
(3 answers)
Closed 2 years ago.
I'm trying to query the most important information from wikipedia articles using the wikimedia API. Within my code I have the following line:
WikiArticleModel article = await response.Content.ReadAsAsync<WikiArticleModel>().ConfigureAwait(false);
This is a example of the way my JSON object looks like when testing on the article from the planet Jupiter:
{
"batchcomplete": "",
"query": {
"normalized": [
{
"from": "jupiter",
"to": "Jupiter"
}
],
"pages": {
"38930": {
"pageid": 38930,
"ns": 0,
"title": "Jupiter",
"extract": ">>> Her comes the first section of the article, which I deleted to make
this shorter <<<",
"description": "Fifth planet from the Sun and largest planet in the Solar System",
"descriptionsource": "local",
"original": {
"source": "https://upload.wikimedia.org/wikipedia/commons/2/2b/Jupiter_and_its_shrunken_Great_Red_Spot.jpg",
"width": 940,
"height": 940
}
}
}
}
}
The question is now, how should my WikiArticleModel class look like? Using the build-in VS Studio too "Paste JSON as class" I get the following result:
public class WikiArticleModel
{
public string batchcomplete { get; set; }
public Query query { get; set; }
}
public class Query
{
public Normalized[] normalized { get; set; }
public Pages pages { get; set; }
}
public class Pages
{
public _38930 _38930 { get; set; }
}
public class _38930
{
public int pageid { get; set; }
public int ns { get; set; }
public string title { get; set; }
public string extract { get; set; }
public string description { get; set; }
public string descriptionsource { get; set; }
public Original original { get; set; }
}
public class Original
{
public string source { get; set; }
public int width { get; set; }
public int height { get; set; }
}
public class Normalized
{
public string from { get; set; }
public string to { get; set; }
}
Which is OK and what I would expect, except for the class _38930, which is just the pageid and would change with every query.
What is the correct way to deserialize this object? Or is it a better approach to just get a object as response and fill the model class manually in this case?
Additionally, I actually only need certain parameters from the JSON object (e.g. title, extract, description,..) - is there a way to get these directly into a model class containing only the properties I need?
This is the way to do it natively, Pages is actually a Dictionary<int, Page>.
public class WikiArticleModel
{
public string batchcomplete { get; set; }
public Query query { get; set; }
}
public class Query
{
public List<Normalized> normalized { get; set; }
public Pages pages { get; set; }
}
[JsonDictionary]
public class Pages : Dictionary<int, Page> { }
public class Page
{
public int pageid { get; set; }
public int ns { get; set; }
public string title { get; set; }
public string extract { get; set; }
public string description { get; set; }
public string descriptionsource { get; set; }
public Original original { get; set; }
}
public class Original
{
public string source { get; set; }
public int width { get; set; }
public int height { get; set; }
}
public class Normalized
{
public string from { get; set; }
public string to { get; set; }
}
I would recommend using JObject.Parse from Newtonsoft.Json.Linq and parsing it based on the name of the keys that page has. Something like this,
public class Page
{
public int pageid { get; set; }
public int ns { get; set; }
public string title { get; set; }
public string extract { get; set; }
public string description { get; set; }
public string descriptionsource { get; set; }
public Original original { get; set; }
}
public class Original
{
public string source { get; set; }
public int width { get; set; }
public int height { get; set; }
}
public class Normalized
{
public string from { get; set; }
public string to { get; set; }
}
// you can deserialize like this,
var jobj = JObject.Parse(json);
var props = ((JObject)jobj["query"]["pages"]).Properties();
Page page = JsonConvert.DeserializeObject<Page>(jobj["query"]["pages"][props.First().Name].ToString());
You can use a foreach loop on each of the properties of pages and iterate through those as well (instead of using props.First().
I'm expecting this response from the API:
{
"EnterKey":"9876546789039876543567890",
"Id":1441462,
"Category":null,
"job":{
"Id":1020332,
"SortName":"test"
},
"Initiator":null,
"Source":{
"Id":1,
"Description":"data"
},
"BalanceNow":0.0,
"ready":false,
"Others":[
{
"Id":1255080,
"Amount":100.0,
"JobMethod":{
"Id":24,
"Description":"task",
"JobType":{
"Id":1,
"Description":"Other"
}
},
"Notes":null
}
],
"Messages":null,
"Products":[
{
"Tasks":{
"Id":2,
"Description":"Blah..."
},
"Join":null,
"TargetData":{
"PaymentId":1535026,
"WantedNotes":"Looks good",
"Name":"John"
},
"AdminDefinedFee":null,
"Product":"New"
}
]
}
I want to deserialize the above Json Response to get the WantedNotes from TargetData that is inside Products. I wanted it done with Json.NET so i tried doing:
public class datasummary
{
public List<TargetData> Products { get; set; }
}
public class TargetData
{
public string WantedNotes { get; set; }
}
var myresult = JsonConvert.DeserializeObject<datasummary>(jsonresponse);
That don't work. I don't know how that really is done. Can someone please show it's done correct?
Define the class structure like this:
public class Job
{
public int Id { get; set; }
public string SortName { get; set; }
}
public class Source
{
public int Id { get; set; }
public string Description { get; set; }
}
public class JobType
{
public int Id { get; set; }
public string Description { get; set; }
}
public class JobMethod
{
public int Id { get; set; }
public string Description { get; set; }
public JobType JobType { get; set; }
}
public class Others
{
public int Id { get; set; }
public double Amount { get; set; }
public JobMethod JobMethod { get; set; }
public object Notes { get; set; }
}
public class Tasks
{
public int Id { get; set; }
public string Description { get; set; }
}
public class TargetData
{
public int PaymentId { get; set; }
public string WantedNotes { get; set; }
public string Name { get; set; }
}
public class Product
{
public Tasks Tasks { get; set; }
public object Join { get; set; }
public TargetData TargetData { get; set; }
public object AdminDefinedFee { get; set; }
public string Product { get; set; }
}
public class DataDummary
{
public string EnterKey { get; set; }
public int Id { get; set; }
public object Category { get; set; }
public Job job { get; set; }
public object Initiator { get; set; }
public Source Source { get; set; }
public double BalanceNow { get; set; }
public bool ready { get; set; }
public List<Others> Others { get; set; }
public object Messages { get; set; }
public List<Product> Products { get; set; }
}
Then use:
var myresult = JsonConvert.DeserializeObject < DataSummary > (jsonresponse);
When working with json, you can copy all text from the file, add an new class then go to
Edit > Paste Especial > Paste JSON as Classes.
It will do all the work for you
Then you can use
var myresult = JsonConvert.DeserializeObject <DataSummary> (jsonresponse);
This question already has answers here:
What is the most effective way to parse JSON objects that are dynamically named?
(2 answers)
Closed 3 years ago.
I am trying to parse a Json response in C#, but one of the parent nodes is a date like "2019-07-11." Normally I would just make classes to deserialize my response into, but this date node is throwing me for a loop.
Here is what I am doing. I am getting a JSON response and trying to deserialize it into nice classes:
rc.EndPoint = "https://api.nasa.gov/neo/rest/v1/feed?api_key=xxxxxxxxxxxx";
rc.Method = HttpVerb.GET;
response = rc.MakeRequest();
r = JsonConvert.DeserializeObject<RootAsteroidObject>(response);
Here are my classes:
public class RootAsteroidObject
{
public Links links { get; set; }
public int element_count { get; set; }
public NearEarthObjects near_earth_objects { get; set; }
}
public class NearEarthObjects
{
public string asteroid { get; set; }
}
public class AsteroidInfo
{
public string id { get; set; }
public string neo_reference_id { get; set; }
public string name { get; set; }
public string nasa_jpl_url { get; set; }
public double absolute_magnitude_h { get; set; }
}
In my RootAsteroidOjbect object after parsing it shows the element_count and links info just fine. However, the near_earth_objects is null. I realize this is because public class AsteroidInfo isn't in the response. The node has the name 2019-07-13. I don't know how to populate my AsteroidInfo class with this information.
Here is the first part of the JSON response I'm working with:
{
"links": {
"next": "http://www.neowsapp.com/rest/v1/feed?start_date=2019-07-18&end_date=2019-07-25&detailed=false&api_key=xxxxxxxxxxxxxxxxxxxxxxx",
"prev": "http://www.neowsapp.com/rest/v1/feed?start_date=2019-07-04&end_date=2019-07-11&detailed=false&api_key=xxxxxxxxxxxxxxxxxxxxxxxx",
"self": "http://www.neowsapp.com/rest/v1/feed?start_date=2019-07-11&end_date=2019-07-18&detailed=false&api_key=xxxxxxxxxxxxxxxxxxxxxxxx"
},
"element_count": 70,
"near_earth_objects": {
"2019-07-13": [
{
"links": {
"self": "http://www.neowsapp.com/rest/v1/neo/3842954?api_key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
},
"id": "3842954",
"neo_reference_id": "3842954",
"name": "(2019 MW1)",
"nasa_jpl_url": "http://ssd.jpl.nasa.gov/sbdb.cgi?sstr=3842954",
"absolute_magnitude_h": 24.505,
"estimated_diameter": {
"kilometers": {
"estimated_diameter_min": 0.0333852764,
"estimated_diameter_max": 0.0746517476
},
I would like to know an approach to get the info under the 2019-07-13 node.
Thanks
Firstly, please note it makes it extremely difficult to help you when you have malformed data
Secondly, NearEarthObjects is a dictionary of something
public Dictionary<DateTime , AsteroidInfo[]> near_earth_objects { get; set; }
Full Example
public class Links
{
public string next { get; set; }
public string prev { get; set; }
public string self { get; set; }
}
public class Links2
{
public string self { get; set; }
}
public class Kilometers
{
public double estimated_diameter_min { get; set; }
public double estimated_diameter_max { get; set; }
}
public class EstimatedDiameter
{
public Kilometers kilometers { get; set; }
}
public class AsteroidInfo
{
public Links2 links { get; set; }
public string id { get; set; }
public string neo_reference_id { get; set; }
public string name { get; set; }
public string nasa_jpl_url { get; set; }
public double absolute_magnitude_h { get; set; }
public EstimatedDiameter estimated_diameter { get; set; }
}
public class RootObject
{
public Links links { get; set; }
public int element_count { get; set; }
public Dictionary<DateTime , AsteroidInfo[]> near_earth_objects { get; set; }
}
Usage
var result = JsonConvert.DeserializeObject<RootObject>(response);
Note : The DateTime seems to work with my testing, however it maybe culture dependent
This question already has answers here:
How can I deserialize JSON with C#?
(19 answers)
Closed 5 years ago.
I am trying to parse JSON response using newtownsoft.json trying to parse the followers count and writeline.
This is the code:
using Newtonsoft.Json;
using System;
using System.IO;
using System.Net;
namespace J2C
{
class Checker
{
static void Main(string[] args)
{
var client = new WebClient();
var text = client.DownloadString("https://www.instagram.com/2saleapp/?__a=1");
User userObject = JsonConvert.DeserializeObject<User>(text);
Console.WriteLine("Followers count =" + userObject.followed_by);
Console.ReadKey();
}
}
}
and this is the API response:
{
"user": {
"biography": "Install 2Sale app to post your AD instantly!\nSnap, post, and sell. Its time to sale.",
"blocked_by_viewer": false,
"country_block": false,
"external_url": "http://autoigs.com/2sale_install",
"external_url_linkshimmed": "http://l.instagram.com/?u=http%3A%2F%2Fautoigs.com%2F2sale_install&e=ATMoKdz87_iz044M0ebrfU95WQT7JqBpnlGiGH9UDOsn7dRax7G6ZMxjh7wMuHY",
"followed_by": {
"count": 6511
},
"followed_by_viewer": false,
"follows": {
"count": 19
},
I just want to WriteLine Followed_by count numbers.
Any one can help me?
thank you
Copy the raw json to the clipboard. In Visual Studio menu select Edit > Paste Special > Paste JSON As Classes (this item is present at least since version VS2015. For earlier versions see). This will generate a set of classes.
public class Rootobject
{
public User user { get; set; }
public string logging_page_id { get; set; }
}
public class User
{
public string biography { get; set; }
public bool blocked_by_viewer { get; set; }
public bool country_block { get; set; }
public string external_url { get; set; }
public string external_url_linkshimmed { get; set; }
public Followed_By followed_by { get; set; }
public bool followed_by_viewer { get; set; }
public Follows follows { get; set; }
public bool follows_viewer { get; set; }
public string full_name { get; set; }
public bool has_blocked_viewer { get; set; }
public bool has_requested_viewer { get; set; }
public string id { get; set; }
public bool is_private { get; set; }
public bool is_verified { get; set; }
public string profile_pic_url { get; set; }
public string profile_pic_url_hd { get; set; }
public bool requested_by_viewer { get; set; }
public string username { get; set; }
public object connected_fb_page { get; set; }
public Media media { get; set; }
}
public class Followed_By
{
public int count { get; set; }
}
public class Follows
{
public int count { get; set; }
}
public class Media
{
public Node[] nodes { get; set; }
public int count { get; set; }
public Page_Info page_info { get; set; }
}
public class Page_Info
{
public bool has_next_page { get; set; }
public string end_cursor { get; set; }
}
public class Node
{
public string __typename { get; set; }
public string id { get; set; }
public bool comments_disabled { get; set; }
public Dimensions dimensions { get; set; }
public object gating_info { get; set; }
public string media_preview { get; set; }
public Owner owner { get; set; }
public string thumbnail_src { get; set; }
public object[] thumbnail_resources { get; set; }
public bool is_video { get; set; }
public string code { get; set; }
public int date { get; set; }
public string display_src { get; set; }
public string caption { get; set; }
public Comments comments { get; set; }
public Likes likes { get; set; }
public int video_views { get; set; }
}
public class Dimensions
{
public int height { get; set; }
public int width { get; set; }
}
public class Owner
{
public string id { get; set; }
}
public class Comments
{
public int count { get; set; }
}
public class Likes
{
public int count { get; set; }
}
Next, use the Rootobject. It's supposed to work.
var client = new WebClient();
var text = client.DownloadString("https://www.instagram.com/2saleapp/?__a=1");
Rootobject rootObject = JsonConvert.DeserializeObject<Rootobject>(text);
Console.WriteLine("Followers count =" + rootObject.user.followed_by.count);
In general, you should change the naming to conform to the generally accepted naming rules. You should use the JsonProperty attribute.
public class Rootobject
{
[JsonProperty("user")]
public User User { get; set; }
[JsonProperty("logging_page_id")]
public string LoggingPageId { get; set; }
}
And so on.
Create a class with name User in order to deserialize json string to User.
public class User
{
public string biography { get; set; }
public bool blocked_by_viewer { get; set; }
public bool country_block { get; set; }
public string external_url { get; set; }
public string external_url_linkshimmed { get; set; }
public FollowedBy followed_by { get; set; }
public string followed_by_viewer { get; set; }
public Follow follows { get; set; }
}
public class FollowedBy
{
public int count { get; set; }
}
public class Follow
{
public int count { get; set; }
}
After getting json string result using the below line for DeserializeObject to User and then assign it to new User object , after that use userObject for showing result.
User userObject = JsonConvert.DeserializeObject<User>(jsonString);
Now you have a user object that fill property with the API response.
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);