read json, repeating group - json

I'm trying to make a windows phone application that reads a json file from a website. This json file has a repeating group and I can't seem to get the program to read all the groups.
This is an example of the json output:
{
"program":{
"title":"Carl Schmitz",
"image_url":"http:\/\/q-music.be\/sites\/2009.q-music.be\/files\/NOA.jpg"
},
"noa":[
{
"title":"Behind Blue Eyes",
"artist":"LIMP BIZKIT",
"itunes_link":"http:\/\/clk.tradedoubler.com\/click?p=24379&a=1256924?url=http:\/\/itunes.apple.com\/be\/album\/behind-blue-eyes\/id14915153?i=14915155&uo=4&partnerId=2003"
},
{
"title":"Alone Again",
"artist":"ALYSSA REID",
"itunes_link":"http:\/\/clk.tradedoubler.com\/click?p=24379&a=1256924?url=http:\/\/itunes.apple.com\/be\/album\/alone-again-original-mix\/id496520410?i=496520415&uo=4&partnerId=2003"
}
]
}
Can someone explain me how to read this json?

Your class structure should look something like this. I used the awesome json2csharp to generate it:
Then you should be able to deserialize directly into the RootObject. You didn't mention which serializer you were using, so the actual deserialization isn't shown here (yet).
public class Program
{
public string title { get; set; }
public string image_url { get; set; }
}
public class Noa
{
public string title { get; set; }
public string artist { get; set; }
public string itunes_link { get; set; }
}
public class RootObject
{
public Program program { get; set; }
public List<Noa> noa { get; set; }
}

Related

Need a help to deserialized nested json response

with the web api getting following response, want help to deserialize following json response in vb.net.
{
"data": {
"getReport": {
"report_date": "April 20, 2020",
"report_date_iso": "2020-04-20",
"links": {
"__typename": "Links",
"proportions_diagram": null
},
"results": {
"shape_and_cutting_style": "Emerald Cut",
"data": {
"shape": {
"shape_category": "F"
},
"girdle": null,
"inscription_graphics": []
}
},
"quota": {
"remaining": 4971
}
}
}
}
Thanks in advance
This worked perfect for me on .NET Core 3.1.
To test it:
In Visual Studio 2019, create a winform in .NET Core 3.1. Be sure it has the NuGet package for Newtonsoft.JSON.
Add a button called btnJsonConvTest, and a textbox called txtJSONinput.
Add a new class file to the project - name doesn't matter. Delete standard content from the file.
Select and copy your JSON. In Visual Studio, click Edit > Paste Special > Paste JSON as Classes. This will create the class structure you see below.
Add the bits of code from below. Note that I gave my class the name JSONTestObject.
Run your program, paste your JSON test string into the text box, and click the button.
Code:
using Newtonsoft.Json;
Button click event:
private void btnJsonConvTest_Click(object sender, EventArgs e)
{
JSONTestObject testobj = JsonConvert.DeserializeObject<JSONTestObject>(txtJSONinput.Text);
String res = JsonConvert.SerializeObject(testobj);
MessageBox.Show(res);
}
And the class that VS created for us:
public class JSONTestObject
{
public Data data { get; set; }
}
public class Data
{
public Getreport getReport { get; set; }
}
public class Getreport
{
public string report_date { get; set; }
public string report_date_iso { get; set; }
public Links links { get; set; }
public Results results { get; set; }
public Quota quota { get; set; }
}
public class Links
{
public string __typename { get; set; }
public object proportions_diagram { get; set; }
}
public class Results
{
public string shape_and_cutting_style { get; set; }
public Data1 data { get; set; }
}
public class Data1
{
public Shape shape { get; set; }
public object girdle { get; set; }
public object[] inscription_graphics { get; set; }
}
public class Shape
{
public string shape_category { get; set; }
}
public class Quota
{
public int remaining { get; set; }
}
When I test it, I get the same JSON string back out as went into it, thus proving that both the serialization and deserialization methods correctly move data in and out of the class properties.

Deserialize JSON string embedded within JSON directly

I'm using .netcore 3.1 and I'm using System.Text.Json for serialization and deserialization. I didn't know how to phrase my question precisely. I looked around but couldn't find a direct answer for my question.
Apologies if it's a duplicate.
This is a sample JSON response.
{
"properties": {
"subscriptionId": "sub1",
"usageStartTime": "2015-03-03T00:00:00+00:00",
"usageEndTime": "2015-03-04T00:00:00+00:00",
"instanceData": "{\"Microsoft.Resources\":{\"resourceUri\":\"resourceUri1\",\"location\":\"Alaska\",\"tags\":null,\"additionalInfo\":null}}",
"quantity": 2.4000000000,
"meterId": "meterID1"
}
}
I'm interested in directly parsing instanceData.
If you observe closely, instanceData is an embedded JSON string.
{
"Microsoft.Resources": {
"resourceUri": "resourceUri1",
"location": "Alaska",
"tags": null,
"additionalInfo": null
}
}
Question:
Is it possible to parse this instanceData while the whole Json is being parsed? Can we add some Attributes to instanceData field for direct parsing? Right now, I'm accessing the string from the parsed model class and parsing instanceData separately.
This is what I'm doing right now (something like this):
JsonSerializer.Deserialize<MicrosoftResources>(parsedResponse.instanceData).
I have already built model classes for instanceData and other entities. Currently, instanceData is of type string in my root model class.
I'm interested in directly parsing instanceData. If you observe closely, instanceData is an embedded JSON string
Is it possible to parse this instanceData while the whole Json is being parsed?
You can achieve above requirement by creating and using a custom converter, like below.
public class ResConverter : JsonConverter<InstanceData>
{
public override InstanceData Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
//you can implement it based on your actual requirement
//...
string jsonData = reader.GetString();
var instanceData = System.Text.Json.JsonSerializer.Deserialize<InstanceData>(jsonData);
return instanceData;
}
Model Classes
public class MyModel
{
public Properties Properties { get; set; }
}
public class Properties
{
public string SubscriptionId { get; set; }
public DateTimeOffset UsageStartTime { get; set; }
public DateTimeOffset UsageEndTime { get; set; }
[JsonConverter(typeof(ResConverter))]
public InstanceData InstanceData { get; set; }
public double Quantity { get; set; }
public string MeterId { get; set; }
}
public class InstanceData
{
[JsonPropertyName("Microsoft.Resources")]
public MicrosoftResources MicrosoftResources { get; set; }
}
public class MicrosoftResources
{
public string ResourceUri { get; set; }
public string Location { get; set; }
public object Tags { get; set; }
public object AdditionalInfo { get; set; }
}
Test code and result
var jsondata = "{\"Properties\":{\"SubscriptionId\":\"sub1\",\"UsageStartTime\":\"2015-03-03T00:00:00+00:00\",\"UsageEndTime\":\"2015-03-04T00:00:00+00:00\",\"InstanceData\":\"{\\u0022Microsoft.Resources\\u0022:{\\u0022ResourceUri\\u0022:\\u0022resourceUri1\\u0022,\\u0022Location\\u0022:\\u0022Alaska\\u0022,\\u0022Tags\\u0022:null,\\u0022AdditionalInfo\\u0022:null}}\",\"Quantity\":2.4,\"MeterId\":\"meterID1\"}}";
MyModel myModel = System.Text.Json.JsonSerializer.Deserialize<MyModel>(jsondata);
If you can change the instanceData to Json instead of string like this.
{
"properties": {
"subscriptionId": "sub1",
"usageStartTime": "2015-03-03T00:00:00+00:00",
"usageEndTime": "2015-03-04T00:00:00+00:00",
"instanceData": {"Microsoft.Resources":{"resourceUri":"resourceUri1","location":"Alaska","tags":null,"additionalInfo":null}},
"quantity": 2.4000000000,
"meterId": "meterID1"
}
}
You can easily deserialize your Json using the example below.
Model Classes:
public partial class Properties
{
[JsonPropertyName("properties")]
public PropertiesClass PropertiesProperties { get; set; }
}
public partial class PropertiesClass
{
[JsonPropertyName("subscriptionId")]
public string SubscriptionId { get; set; }
[JsonPropertyName("usageStartTime")]
public DateTimeOffset UsageStartTime { get; set; }
[JsonPropertyName("usageEndTime")]
public DateTimeOffset UsageEndTime { get; set; }
[JsonPropertyName("instanceData")]
public InstanceData InstanceData { get; set; }
[JsonPropertyName("quantity")]
public double Quantity { get; set; }
[JsonPropertyName("meterId")]
public string MeterId { get; set; }
}
public partial class InstanceData
{
[JsonPropertyName("Microsoft.Resources")]
public MicrosoftResources MicrosoftResources { get; set; }
}
public partial class MicrosoftResources
{
[JsonPropertyName("resourceUri")]
public string ResourceUri { get; set; }
[JsonPropertyName("location")]
public string Location { get; set; }
[JsonPropertyName("tags")]
public object Tags { get; set; }
[JsonPropertyName("additionalInfo")]
public object AdditionalInfo { get; set; }
}
Usage:
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
class Program
{
static void Main(string[] args)
{
// escaped version, just for demo
var json =
"{\r\n \"properties\": {\r\n \"subscriptionId\": \"sub1\",\r\n \"usageStartTime\": \"2015-03-03T00:00:00+00:00\",\r\n \"usageEndTime\": \"2015-03-04T00:00:00+00:00\",\r\n \"instanceData\": {\"Microsoft.Resources\":{\"resourceUri\":\"resourceUri1\",\"location\":\"Alaska\",\"tags\":null,\"additionalInfo\":null}},\r\n \"quantity\": 2.4000000000,\r\n \"meterId\": \"meterID1\"\r\n }\r\n}";
var props = JsonSerializer.Deserialize<Properties>(json);
}
}
Props will have all of the data. I hope this helps.

C# JSON deserialization returns null

I'm trying to deserialize some statistics in JSON format from valve's API. The code below doesn't throw any exceptions when deserializing, only when trying to use the statistics afterwards. None of the statistics have a value after deserialization. Valve's response looks like this:
"playerstats":{
"steamID":"",
"gameName":"",
"stats":[
{
"name":"deaths",
"value":5062
}, etc etc..
This is my Rust class (Rust being the game I'm getting statistics from.):
public class Rust
{
public int steamID { get; set; }
public string gameName { get; set; }
public Array stats { get; set; }
}
And this is the deserialization code:
Rust getStats = JsonConvert.DeserializeObject<Rust>(str);
foreach (var stat in getStats.stats) //< ----- Exception: Object reference not set to an instance of an object.
{
parsed += stat.ToString();
}
'parsed' is then returned and used to print out all statistics and 'str' is the json response from Valve. I pasted the entire JSON response on pastebin in-case the above data isn't enough: https://pastebin.com/uJZSTF3G
I've tried naming some of the statistics individually in the Rust class instead of using an Array.
I expect the output to show all of the deserialized statistics for example in a console.
As #Bagus Tesa suggested, try something like...
public class Rust
{
public int steamID { get; set; }
public string gameName { get; set; }
public List<RustStat> stats { get; set; }
}
public class RustStat
{
public string name { get; set; }
public string value { get; set; }
}
Edit
I changed the steamID property to string and added the full code below. This compiled for me successfully. Hope this helps!
public class Valve
{
public Rust playerstats { get; set; }
}
public class Rust
{
public string steamID { get; set; }
public string gameName { get; set; }
public List<RustStat> stats { get; set; }
}
public class RustStat
{
public string name { get; set; }
public string value { get; set; }
}
Valve valve = JsonConvert.DeserializeObject<Valve>(str);
foreach (RustStat stat in valve.playerstats.stats)
{
}

JSON.NET Error reading string. Unexpected token: StartObject. Path 'responseData',

I am trying to deserialize this link , but I keep getting this error.
Error reading string. Unexpected token: StartObject. Path 'responseData'.
From what i have googled, the problem seems to be the setup of my object I'm trying to deserialize into. Below is my class:
public class FeedSearchResult
{
[JsonProperty("responseData")]
public String ResponseData { get; set; }
[JsonProperty("query")]
public String Query { get; set; }
[JsonProperty("entries")]
public string[] Entries { get; set; }
[JsonProperty("responseDetails")]
public object ResponseDetails { get; set; }
[JsonProperty("responseStatus")]
public String ResponseStatsu { get; set; }
}
public class ResultItem
{
[JsonProperty("title")]
public String Title { get; set; }
[JsonProperty("url")]
public String Url { get; set; }
[JsonProperty("link")]
public String Link { get; set; }
}
What am I doing wrong in my class? Any help would be greatly appreciated.
Your data model only has two levels of nesting, but the JSON returned has three. If you look at the formatted JSON using https://jsonformatter.curiousconcept.com/ you will see:
{
"responseData":{
"query":"Official Google Blogs",
"entries":[
{
"url":"https://googleblog.blogspot.com/feeds/posts/default",
"title":"\u003cb\u003eOfficial Google Blog\u003c/b\u003e",
"contentSnippet":"\u003cb\u003eOfficial\u003c/b\u003e weblog, with news of new products, events and glimpses of life inside \u003cbr\u003e\n\u003cb\u003eGoogle\u003c/b\u003e.",
"link":"https://googleblog.blogspot.com/"
},
In particular your data model has responseData as a String when it needs to be a contained object. This is the specific cause of the exception.
If you upload the JSON to http://json2csharp.com/ you will get the following data model, which can be used to deserialize this JSON:
public class ResultItem
{
public string url { get; set; }
public string title { get; set; }
public string contentSnippet { get; set; }
public string link { get; set; }
}
public class ResponseData
{
public string query { get; set; }
public List<ResultItem> entries { get; set; }
}
public class RootObject
{
public ResponseData responseData { get; set; }
//Omitted since type is unclear.
//public object responseDetails { get; set; }
public int responseStatus { get; set; }
}

Parsing JSON in C# 4.0

Can anyone help me to parse this JSON into an object IN C# 4.0. I have spent the last two days trying.
I have JSON.NET and several other peoples suggestions to no avail.
I thought it would be best just to give the JSON sample and to ask for your suggestions.
{
"message-count":"1",
"messages":[
{"to":"441234567890",
"messageprice":"0.02900000",
"status":"0",
"messageid":"030000001DFE2CB1",
"remainingbalance":"1.56500000",
"network":"23433"}
]
}
Many thanks,
Adrian
p.s Their is some nice code here, if you want to use github. https://github.com/lukesampson/HastyAPI.Nexmo
I will cheat and create C# classes quickly using this tool: http://json2csharp.com/ (or just discovered http://jsonclassgenerator.codeplex.com/)
Then I change C# classes to my liking
public class MessagesJSON
{
public int MessageCount { get; set; }
public List<Message> Messages { get; set; }
}
public class Message
{
public string To { get; set; }
public double MessagePrice { get; set; }
public int Status { get; set; }
public string MessageId { get; set; }
public double RemainingBalance { get; set; }
public string Network { get; set; }
}
MessagesJSON is just a name I made that represents the JSON object that you are passing to C#.
I pass the JSON string from the client, e.g.
{\"MessageCount\":1,\"Messages\":[{\"To\":\"441234567890\",\"MessagePrice\":0.029,\"Status\":0,\"MessageId\":\"030000001DFE2CB1\",\"RemainingBalance\":1.565,\"Network\":\"23433\"}]
Then I can use JSON.NET to convert JSON to C# objects:
public void YourMethod(MessagesJSON json) {
var result = JsonConvert.DeserializeObject<MessagesJSON>(json);
}
Here's the result:
Watch out for capitalisation.
If you want to use lower-case JSON keys only, change the C# classes to lower-case, e.g. public double messageprice { get; set; }
C# classes:
public class MessagesJSON
{
public int message_count { get; set; }
public List<Message> messages { get; set; }
}
public class Message
{
public string to { get; set; }
public string messageprice { get; set; }
public string status { get; set; }
public string messageid { get; set; }
public string remainingbalance { get; set; }
public string network { get; set; }
}
This is as close to your JSON as you want:
{\"message_count\":1,\"messages\":[{\"to\":\"441234567890\",\"messageprice\":\"0.02900000\",\"status\":\"0\",\"messageid\":\"030000001DFE2CB1\",\"remainingbalance\":\"1.56500000\",\"network\":\"23433\"}]}
or use one of these solutions if you really like CamelCasing:
CamelCase only if PropertyName not explicitly set in Json.Net?
JObject & CamelCase conversion with JSON.Net
I myself prefer attributes
public class Message
{
[JsonProperty("to")]
public string To { get; set; }
[JsonProperty("messageprice")]
public string MessagePrice { get; set; }
[JsonProperty("status")]
public string Status { get; set; }
[JsonProperty("messageid")]
public string MessageId { get; set; }
[JsonProperty("remainingbalance")]
public string RemainingBalance { get; set; }
[JsonProperty("network")]
public string Network { get; set; }
}
Pass your string:
"{\"message_count\":1,\"messages\":[{\"to\":\"441234567890\",\"messageprice\":\"0.02900000\",\"status\":\"0\",\"messageid\":\"030000001DFE2CB1\",\"remainingbalance\":\"1.56500000\",\"network\":\"23433\"}]}"
but get the pretty C# property names:
Create objects with the same structure as the json and call.
JsonConvert.DeserializeObject<Entity>(json);
Edit. You have to use JSON.NET if u wanna do it this way.