Deserializing Json from iTunes store into C# object - c#

I have the following Json returned from iTunes (I have replaced some details for privacy such as username and review content)
{"feed":{"author":{"name":{"label":"iTunes Store"}, "uri":{"label":"http://www.apple.com/uk/itunes/"}}, "entry":[
{"author":{"uri":{"label":"https://itunes.apple.com/gb/reviews/ID"}, "name":{"label":"Username"}, "label":""}, "im:version":{"label":"3.51"}, "im:rating":{"label":"4"}, "id":{"label":"12345"}, "title":{"label":"Review title"}, "content":{"label":"Review contents", "attributes":{"type":"text"}}, "link":{"attributes":{"rel":"related", "href":"https://itunes.apple.com/gb/review?reviewid"}}, "im:voteSum":{"label":"0"}, "im:contentType":{"attributes":{"term":"Application", "label":"Application"}}, "im:voteCount":{"label":"0"}},
// more entries ...
I want to deserialize this into a class. I only need the Review Title, Review contents, and the "im:rating" (which is the number of stars). However, I'm struggling due to the nested Json and the use of keys of how to extract this data. So far I have created a class ready to deserialize, and I have AppStoreData appStoreData = JsonConvert.DeserializeObject<AppStoreData>(stringResult); to deserialize it
public class AppStoreData {
}
My problem is that I don't know what to put inside the class to get the info I need from the Json. I have tried things such as:
public string title {get; set;}
public string content {get; set;}
public string imrating {get; set;}
However this doesn't work. I also think im:rating is an invalid name in C#.
Can anyone please help? Thank you

To get around the issue with im:rating you can use a JsonProperty attribute
[JsonProperty("im:rating")]
public Id ImRating { get; set; }
The issue with converting things like Label to string property is that it's not a string but an object in the input file.
You need something like
[JsonProperty("title")]
public Id Title { get; set; }
where Id is a class
public class Id
{
[JsonProperty("label")]
public string Label { get; set; }
}
Or write a deserializer that converts it to string for you.
I would suggest trying out one of many free code generators like https://app.quicktype.io/?l=csharp or http://json2csharp.com/ to get a headstart and edit everything to your liking afterwards.

I suggest using json2csharp to convert the json to c# model and change the invalid attributes by adding JsonProperty
public class Name
{
public string label { get; set; }
}
public class Uri
{
public string label { get; set; }
}
public class Author
{
public Name name { get; set; }
public Uri uri { get; set; }
}
public class Uri2
{
public string label { get; set; }
}
public class Name2
{
public string label { get; set; }
}
public class Author2
{
public Uri2 uri { get; set; }
public Name2 name { get; set; }
public string label { get; set; }
}
public class ImVersion
{
public string label { get; set; }
}
public class ImRating
{
public string label { get; set; }
}
public class Id
{
public string label { get; set; }
}
public class Title
{
public string label { get; set; }
}
public class Attributes
{
public string type { get; set; }
}
public class Content
{
public string label { get; set; }
public Attributes attributes { get; set; }
}
public class Attributes2
{
public string rel { get; set; }
public string href { get; set; }
}
public class Link
{
public Attributes2 attributes { get; set; }
}
public class ImVoteSum
{
public string label { get; set; }
}
public class Attributes3
{
public string term { get; set; }
public string label { get; set; }
}
public class ImContentType
{
public Attributes3 attributes { get; set; }
}
public class ImVoteCount
{
public string label { get; set; }
}
public class Entry
{
public Author2 author { get; set; }
[JsonProperty(PropertyName = "im:version")]
public ImVersion imversion { get; set; }
[JsonProperty(PropertyName = "im:rating")]
public ImRating imrating { get; set; }
public Id id { get; set; }
public Title title { get; set; }
public Content content { get; set; }
public Link link { get; set; }
[JsonProperty(PropertyName = "im:voteSum")]
public ImVoteSum imvoteSum { get; set; }
[JsonProperty(PropertyName = "im:contentType")]
public ImContentType imcontentType { get; set; }
[JsonProperty(PropertyName = "im:voteCount")]
public ImVoteCount imvoteCount { get; set; }
}
public class Feed
{
public Author author { get; set; }
public List<Entry> entry { get; set; }
}
public class RootObject5
{
public Feed feed { get; set; }
}
Once the model is ready you can use JsonConvert.DeserializeObject to convert the JSON to c# object
using (StreamReader r = new StreamReader(filepath)) {
string json = r.ReadToEnd();
var newEmps = JsonConvert.DeserializeObject<RootObject5>(json);
Console.WriteLine(newEmps.feed.entry[0].imvoteCount.label);
}

Related

Alternative to naming an c# class attribute '#' when converting files with mentioned attribute from json [duplicate]

I have a JSON request which has follwing structure:
"formats": {
"flash_embed": "http://a3.vikiassets.com/assets/vikiplayer-922746a667cfd38137a7e45df6ba1b95.swf?auto_play=true&language_codes=en&media_id=74965&partner=16&source=api_v3",
"m3u8": "http://wpc.354a.edgecastcdn.net/00354A/videos/encoded/74965/ios.m3u8",
"res-150p": "http://wpc.354a.edgecastcdn.net/00354A/videos/encoded/74965_mp4cell_150.mp4",
"res-240p": "http://wpc.354a.edgecastcdn.net/00354A/videos/encoded/74965_240p.mp4",
"res-270p": "http://wpc.354a.edgecastcdn.net/00354A/videos/encoded/74965_270p.mp4",
"res-360p": "http://wpc.354a.edgecastcdn.net/00354A/videos/encoded/74965_360p.mp4",
"res-480p": "http://wpc.354a.edgecastcdn.net/00354A/videos/encoded/74965_480p.mp4",
"res-720p": "http://wpc.354a.edgecastcdn.net/00354A/videos/encoded/74965_720p.mp4"
}
}
Now res-150p, says invalid name in C# and if I give another name to it then while desiralizing I am not getting any values, that is null inside res-150p.
Edit:
[Serializable]
MoviesListRootObject is the root Object which Contains Response and then Response Contains Formats
public class MoviesListRootObject
{
public int count { get; set; }
public Pagination pagination { get; set; }
public List<Response> response { get; set; }
}
[Serializable]
public class Response
{
public int id { get; set; }
public int channel_id { get; set; }
public string title { get; set; }
public string title_language { get; set; }
public string description { get; set; }
public string description_language { get; set; }
public string created_at { get; set; }
public string uri { get; set; }
public string web_uri { get; set; }
public List<object> genres { get; set; }
public string origin_country { get; set; }
public string image { get; set; }
public Subtitles subtitles { get; set; }
public Formats formats { get; set; }
}
[Serializable]
public class Formats
{
public string flash_embed { get; set; }
public string m3u8 { get; set; }
public string __invalid_name__res150p { get; set; }
public string __invalid_name__res240p { get; set; }
public string __invalid_name__res270p { get; set; }
public string __invalid_name__res360p { get; set; }
public string __invalid_name__res480p { get; set; }
public string __invalid_name__res720p { get; set; }
public string __invalid_name__flv480p { get; set; }
public string __invalid_name__flv360p { get; set; }
public string __invalid_name__flv270p { get; set; }
public string __invalid_name__flvvp6360p { get; set; }
public string __invalid_name__flvvp6270p { get; set; }
}
You have to decorate your Formats properties with JsonProperty attributes to tell it what goes where if the name does not exactly match:
partial class Formats
{
[JsonProperty("res-150p")]
public string __invalid_name__res150p {get; set;}
}
See also Using JsonConvert.DeserializeObject to deserialize Json to a C# POCO class

JSON DeserializeObject to Model without Key Name

I currently have JSON coming in as follows:
{"36879":[{"min_qty":1,"discount_type":"%","csp_price":10}],"57950":[{"min_qty":1,"discount_type":"flat","csp_price":650}]}
This contains a list of the following records
ProductId
MinQty
DiscountType
Price
I need to deserialize this into the following model:
public class CustomerSpecificPricing
{
string productId { get; set; }
public virtual List<CustomerSpecificPricingDetail> CustomerSpecificPricingDetails { get; set; }
}
public class CustomerSpecificPricingDetail
{
public string min_qty { get; set; }
public string discount_type { get; set; }
public string csp_price { get; set; }
}
The problem is that the "productId" of each record is missing the key name.
If I run my JSON through J2C, I get the following:
public class 36879 {
public int min_qty { get; set; }
public string discount_type { get; set; }
public int csp_price { get; set; }
}
public class 57950 {
public int min_qty { get; set; }
public string discount_type { get; set; }
public int csp_price { get; set; }
}
public class Root {
public List<_36879> _36879 { get; set; }
public List<_57950> _57950 { get; set; }
}
Which is obviously incorrect.
How would I deserialize my object correctly?
You would need to deserialize it into a dictionary first and then map it into the format you require after. Something like this should work:
var dict = JsonConvert.DeserializeObject<Dictionary<string, IEnumerable<CustomerSpecificPricingDetail>>>();
var result = dict.Select(kvp => new CustomerSpecificPricing { ProductId = Int32.Parse(kvp.Key), CustomerSpecificPricingDetails = kvp.Value });
Id also recommend you follow the conventional standards of naming. In this case properties in classes should be PascalCase,
e.g. your classes now become:
public class CustomerSpecificPricing
{
[JsonProperty("productId ")]
public string ProductId { get; set; }
public virtual List<CustomerSpecificPricingDetail> CustomerSpecificPricingDetails { get; set; }
}
and
public class CustomerSpecificPricingDetail
{
[JsonProperty("min_qty")]
public string MinQty { get; set; }
[JsonProperty("discount_type ")]
public string DiscountType { get; set; }
[JsonProperty("csp_price ")]
public string CspPrice { get; set; }
}

c# load Json into inherited class

I have a C# classes and I need to parse JSON into it.
The class has a List<> from another class.
The class structure is like this.
public class OrderFund {
public int OrderID { get; set; }
public int BrokerID { get; set; }
public string SettlementMethod { get; set; }
public List<SettlementSap> SettlementsSap { get; set; }
}
public class SettlementSap {
public string SapMonetaryAccountNo { get; set; }
public string SapMonetaryAccountType { get; set; }
public string SapMonetaryAccountOffice { get; set; }
}
My JSON is like this.
{
"settlementMethod": "SAP",
"BrokerID": 1,
"OrderID": 1,
"Settlements": [
{
"SapMonetaryAccountNo": "400245892464",
"SapMonetaryAccountType": "CA",
"SapMonetaryAccountOffice": "AR"
}
]
}
I load my JSON file like this...
static OrderFund LoadJson(string file) {
string dire = Directory.GetCurrentDirectory();
using (StreamReader r = new StreamReader(dire + "\\" + file)) {
string json = r.ReadToEnd();
OrderFund items = JsonConvert.DeserializeObject<OrderFund>(json);
return items;
}
}
The data load fine into OrderFun Class but OrderFund.SettlementsSap is null.
How can I load Settlements into SettlementsSap?
That's because you have named the field SettlementsSap but your Json field is called Settlements...
You could rename the field in your class;
public class OrderFund
{
public int OrderID { get; set; }
public int BrokerID { get; set; }
public string SettlementMethod { get; set; }
public List<SettlementSap> Settlements { get; set; }
}
or add a [JsonProperty("Settlements")]
attribute to the field like so;
public class OrderFund
{
public int OrderID { get; set; }
public int BrokerID { get; set; }
public string SettlementMethod { get; set; }
[JsonProperty("Settlements")]
public List<SettlementSap> SettlementsSap { get; set; }
}
You just use a function of Visual Studio which convert your json into a model class
Goto: Edit -> Paste special -> Paste JSON as Class
The model class created by this feature will solve your problem
So, visiblely, you must rename SettlementsSap by Settlements
public class OrderFund
{
public string settlementMethod { get; set; }
public int BrokerID { get; set; }
public int OrderID { get; set; }
public Settlement[] Settlements { get; set; }
}
public class Settlement
{
public string SapMonetaryAccountNo { get; set; }
public string SapMonetaryAccountType { get; set; }
public string SapMonetaryAccountOffice { get; set; }
}
The problem is with the naming. In the JSON, the name is Settlements. But in the class definition of OrderFund it is named as SettlementsSap

How should I handle Wordpress rest json in C# when json2csharp is returning an invalid name? [duplicate]

I have a JSON request which has follwing structure:
"formats": {
"flash_embed": "http://a3.vikiassets.com/assets/vikiplayer-922746a667cfd38137a7e45df6ba1b95.swf?auto_play=true&language_codes=en&media_id=74965&partner=16&source=api_v3",
"m3u8": "http://wpc.354a.edgecastcdn.net/00354A/videos/encoded/74965/ios.m3u8",
"res-150p": "http://wpc.354a.edgecastcdn.net/00354A/videos/encoded/74965_mp4cell_150.mp4",
"res-240p": "http://wpc.354a.edgecastcdn.net/00354A/videos/encoded/74965_240p.mp4",
"res-270p": "http://wpc.354a.edgecastcdn.net/00354A/videos/encoded/74965_270p.mp4",
"res-360p": "http://wpc.354a.edgecastcdn.net/00354A/videos/encoded/74965_360p.mp4",
"res-480p": "http://wpc.354a.edgecastcdn.net/00354A/videos/encoded/74965_480p.mp4",
"res-720p": "http://wpc.354a.edgecastcdn.net/00354A/videos/encoded/74965_720p.mp4"
}
}
Now res-150p, says invalid name in C# and if I give another name to it then while desiralizing I am not getting any values, that is null inside res-150p.
Edit:
[Serializable]
MoviesListRootObject is the root Object which Contains Response and then Response Contains Formats
public class MoviesListRootObject
{
public int count { get; set; }
public Pagination pagination { get; set; }
public List<Response> response { get; set; }
}
[Serializable]
public class Response
{
public int id { get; set; }
public int channel_id { get; set; }
public string title { get; set; }
public string title_language { get; set; }
public string description { get; set; }
public string description_language { get; set; }
public string created_at { get; set; }
public string uri { get; set; }
public string web_uri { get; set; }
public List<object> genres { get; set; }
public string origin_country { get; set; }
public string image { get; set; }
public Subtitles subtitles { get; set; }
public Formats formats { get; set; }
}
[Serializable]
public class Formats
{
public string flash_embed { get; set; }
public string m3u8 { get; set; }
public string __invalid_name__res150p { get; set; }
public string __invalid_name__res240p { get; set; }
public string __invalid_name__res270p { get; set; }
public string __invalid_name__res360p { get; set; }
public string __invalid_name__res480p { get; set; }
public string __invalid_name__res720p { get; set; }
public string __invalid_name__flv480p { get; set; }
public string __invalid_name__flv360p { get; set; }
public string __invalid_name__flv270p { get; set; }
public string __invalid_name__flvvp6360p { get; set; }
public string __invalid_name__flvvp6270p { get; set; }
}
You have to decorate your Formats properties with JsonProperty attributes to tell it what goes where if the name does not exactly match:
partial class Formats
{
[JsonProperty("res-150p")]
public string __invalid_name__res150p {get; set;}
}
See also Using JsonConvert.DeserializeObject to deserialize Json to a C# POCO class

How to Deserialize an JSON object with invalid field name in it

I have a JSON request which has follwing structure:
"formats": {
"flash_embed": "http://a3.vikiassets.com/assets/vikiplayer-922746a667cfd38137a7e45df6ba1b95.swf?auto_play=true&language_codes=en&media_id=74965&partner=16&source=api_v3",
"m3u8": "http://wpc.354a.edgecastcdn.net/00354A/videos/encoded/74965/ios.m3u8",
"res-150p": "http://wpc.354a.edgecastcdn.net/00354A/videos/encoded/74965_mp4cell_150.mp4",
"res-240p": "http://wpc.354a.edgecastcdn.net/00354A/videos/encoded/74965_240p.mp4",
"res-270p": "http://wpc.354a.edgecastcdn.net/00354A/videos/encoded/74965_270p.mp4",
"res-360p": "http://wpc.354a.edgecastcdn.net/00354A/videos/encoded/74965_360p.mp4",
"res-480p": "http://wpc.354a.edgecastcdn.net/00354A/videos/encoded/74965_480p.mp4",
"res-720p": "http://wpc.354a.edgecastcdn.net/00354A/videos/encoded/74965_720p.mp4"
}
}
Now res-150p, says invalid name in C# and if I give another name to it then while desiralizing I am not getting any values, that is null inside res-150p.
Edit:
[Serializable]
MoviesListRootObject is the root Object which Contains Response and then Response Contains Formats
public class MoviesListRootObject
{
public int count { get; set; }
public Pagination pagination { get; set; }
public List<Response> response { get; set; }
}
[Serializable]
public class Response
{
public int id { get; set; }
public int channel_id { get; set; }
public string title { get; set; }
public string title_language { get; set; }
public string description { get; set; }
public string description_language { get; set; }
public string created_at { get; set; }
public string uri { get; set; }
public string web_uri { get; set; }
public List<object> genres { get; set; }
public string origin_country { get; set; }
public string image { get; set; }
public Subtitles subtitles { get; set; }
public Formats formats { get; set; }
}
[Serializable]
public class Formats
{
public string flash_embed { get; set; }
public string m3u8 { get; set; }
public string __invalid_name__res150p { get; set; }
public string __invalid_name__res240p { get; set; }
public string __invalid_name__res270p { get; set; }
public string __invalid_name__res360p { get; set; }
public string __invalid_name__res480p { get; set; }
public string __invalid_name__res720p { get; set; }
public string __invalid_name__flv480p { get; set; }
public string __invalid_name__flv360p { get; set; }
public string __invalid_name__flv270p { get; set; }
public string __invalid_name__flvvp6360p { get; set; }
public string __invalid_name__flvvp6270p { get; set; }
}
You have to decorate your Formats properties with JsonProperty attributes to tell it what goes where if the name does not exactly match:
partial class Formats
{
[JsonProperty("res-150p")]
public string __invalid_name__res150p {get; set;}
}
See also Using JsonConvert.DeserializeObject to deserialize Json to a C# POCO class

Categories