I have a nested JSON data to be accessed. The data is structured into nested data which i want to have into one.
I modeled the JSON response into c# model classes
public class Customer1
{
public string district { get; set; }
public string feeder { get; set; }
public string feeder_code { get; set; }
public string transformer { get; set; }
public string dss_code { get; set; }
public string database_match { get; set; }
public string accountnumber { get; set; }
public string meterno { get; set; }
public TransactionalDetails transactional_details { get; set; }
}
public class Customer2
{
public string accountNumber { get; set; }
public string meterNumber { get; set; }
public string phoneNumber { get; set; }
public int billedAmount { get; set; }
public object billedDate { get; set; }
public string lastPayDate { get; set; }
public Lastpayment lastpayment { get; set; }
}
public class Lastpayment
{
public string transactionRef { get; set; }
public int units { get; set; }
public string transactionDate { get; set; }
public string transactionId { get; set; }
public int transactionBookId { get; set; }
public int amountPaid { get; set; }
public int mscPaid { get; set; }
public string invoiceNumber { get; set; }
}
public class Queryresult
{
public string responseMessage { get; set; }
public Customer1 customer1 { get; set; }
public int responseCode { get; set; }
public string status { get; set; }
}
public class Result
{
public ObservableCollection<Customer1> Customer1 { get; set; }
public int row_count { get; set; }
}
public class Root
{
public bool error { get; set; }
public Result result { get; set; }
}
public class TransactionalDetails
{
public Queryresult queryresult { get; set; }
public bool status { get; set; }
}
I also created the following code to access the data using the root.
var data = JsonConvert.DeserializeObject<root>(readTask);
ObservableCollection<Customer1> innerData2 = data.result.Customer1;
My challenge is that i want to have Customer1, Customer2 and last payment data merged into a single collection view.
with what i have done, i can only access customer1 data. how can i access all into a single collection?
I have below Json -
{"property_id":"53863730","name":"Hayat Elhamra","address":{"line_1":"Jeddah","city":"Jeddah","state_province_name":"Jeddah","postal_code":"23212","country_code":"SA","obfuscation_required":false,"localized":{"links":{"ar-SA":{"method":"GET","href":"https://api.ean.com/2.4/properties/content?language=ar-SA&property_id=53863730&include=address"}}}},"location":{"coordinates":{"latitude":21.520902,"longitude":39.158265}},"phone":"20-01145772035","category":{"id":"16","name":"Apartment"},"rank":99999999,"business_model":{"expedia_collect":true,"property_collect":true},"dates":{"added":"2020-06-10T23:03:21.345Z","updated":"2020-06-10T23:03:23.701Z"},"chain":{"id":"0","name":"Independent"},"brand":{"id":"0","name":"Independent"}}
{"property_id":"53183065","name":"Carefully Furnished Bungalow With 2 Bathrooms, 7km From Pula","address":{"line_1":"1 x M 90,3","line_2":"PRIVATE_VACATION_HOME 3","city":"Fazana","state_province_name":"Istria (county)","postal_code":"52212","country_code":"HR","obfuscation_required":true,"localized":{"links":{"hr-HR":{"method":"GET","href":"https://api.ean.com/2.4/properties/content?language=hr-HR&property_id=53183065&include=address"}}}},"ratings":{"property":{"rating":"3.0","type":"Star"}},"location":{"coordinates":{"latitude":44.93,"longitude":13.8}},"phone":"410442743080","category":{"id":"17","name":"Private vacation home"},"rank":99999999,"business_model":{"expedia_collect":true,"property_collect":false},"dates":{"added":"2020-05-13T21:06:42.861Z","updated":"2020-05-18T21:57:39.242Z"},"statistics":{"1073743378":{"id":"1073743378","name":"Number of bedrooms - 2","value":"2"},"1073743380":{"id":"1073743380","name":"Max occupancy - 4","value":"4"},"1073743379":{"id":"1073743379","name":"Number of bathrooms - 2","value":"2"}},"chain":{"id":"7278","name":"Belvilla"},"brand":{"id":"7353","name":"Belvilla"}}
{"property_id":"53182898","name":"Snug Cottage in Pašman With Roofed Terrace","address":{"line_1":"Pasman","city":"Pasman","state_province_name":"Zadar","postal_code":"23260","country_code":"HR","obfuscation_required":true,"localized":{"links":{"hr-HR":{"method":"GET","href":"https://api.ean.com/2.4/properties/content?language=hr-HR&property_id=53182898&include=address"}}}},"ratings":{"property":{"rating":"1.0","type":"Star"}},"location":{"coordinates":{"latitude":43.891571,"longitude":15.423619}},"phone":"410442743080","category":{"id":"11","name":"Cottage"},"rank":99999999,"business_model":{"expedia_collect":true,"property_collect":false},"dates":{"added":"2020-05-13T21:13:49.155Z","updated":"2020-05-27T21:02:31.808Z"},"statistics":{"1073743378":{"id":"1073743378","name":"Number of bedrooms - 2","value":"2"},"1073743380":{"id":"1073743380","name":"Max occupancy - 5","value":"5"},"1073743379":{"id":"1073743379","name":"Number of bathrooms - 1","value":"1"}},"chain":{"id":"7278","name":"Belvilla"},"brand":{"id":"7353","name":"Belvilla"}}
For this I have created below class structure -
public class Property
{
public string property_id { get; set; }
public string name { get; set; }
public Address address { get; set; }
public Location location { get; set; }
public string phone { get; set; }
public Category category { get; set; }
public int rank { get; set; }
public Business_Model business_model { get; set; }
public Dates dates { get; set; }
public Chain chain { get; set; }
public Brand brand { get; set; }
}
public class Address
{
public string line_1 { get; set; }
public string city { get; set; }
public string state_province_name { get; set; }
public string postal_code { get; set; }
public string country_code { get; set; }
public bool obfuscation_required { get; set; }
public Localized localized { get; set; }
}
public class Localized
{
public Links links { get; set; }
}
public class Links
{
public ArSA arSA { get; set; }
}
public class ArSA
{
public string method { get; set; }
public string href { get; set; }
}
public class Location
{
public Coordinates coordinates { get; set; }
}
public class Coordinates
{
public float latitude { get; set; }
public float longitude { get; set; }
}
public class Category
{
public string id { get; set; }
public string name { get; set; }
}
public class Business_Model
{
public bool expedia_collect { get; set; }
public bool property_collect { get; set; }
}
public class Dates
{
public DateTime added { get; set; }
public DateTime updated { get; set; }
}
public class Chain
{
public string id { get; set; }
public string name { get; set; }
}
public class Brand
{
public string id { get; set; }
public string name { get; set; }
}
I have below code where I am getting error -
using (StreamReader streamReader = new StreamReader("d://propertycontent.expediacollect.en-US.json"))
{
using (var json = new JsonTextReader(streamReader))
{
JsonSerializer serializer = new JsonSerializer();
var properties= (List<Property>)serializer.Deserialize(json, typeof(List<Property>));
}
}
Error -
Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[Property]' 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 'property_id', line 1, position 15.'
It is not deserializing because it is not valid json. To make it valid, and to make it a List<Property> add [ to the beginning of the json and ] to the end of the json. Just enclose the json in [ ... ] to make it valid and it will deserialize assuming the rest of it is valid and is not missing any commas or brackets.
try this, you will have to install NewtonsoftJson. It was tested using Visual Studio and Postman and works properly.
var jsonOrig= ...your json
var json = JsonConvert.SerializeObject(jsonOrig);
var jsonObj = JsonConvert.DeserializeObject<DataRoot>(json);
classes
public class DataRoot
{
public string property_id { get; set; }
public string name { get; set; }
public Address address { get; set; }
public Location location { get; set; }
public string phone { get; set; }
public Category category { get; set; }
public int rank { get; set; }
public BusinessModel business_model { get; set; }
public Dates dates { get; set; }
public Chain chain { get; set; }
public Brand brand { get; set; }
}
public class ArSA
{
public string method { get; set; }
public string href { get; set; }
}
public class Links
{
[JsonProperty("ar-SA")]
public ArSA ArSA { get; set; }
}
public class Localized
{
public Links links { get; set; }
}
public class Address
{
public string line_1 { get; set; }
public string city { get; set; }
public string state_province_name { get; set; }
public string postal_code { get; set; }
public string country_code { get; set; }
public bool obfuscation_required { get; set; }
public Localized localized { get; set; }
}
public class Coordinates
{
public double latitude { get; set; }
public double longitude { get; set; }
}
public class Location
{
public Coordinates coordinates { get; set; }
}
public class Category
{
public string id { get; set; }
public string name { get; set; }
}
public class BusinessModel
{
public bool expedia_collect { get; set; }
public bool property_collect { get; set; }
}
public class Dates
{
public DateTime added { get; set; }
public DateTime updated { get; set; }
}
public class Chain
{
public string id { get; set; }
public string name { get; set; }
}
public class Brand
{
public string id { get; set; }
public string name { get; set; }
}
`````
I am trying to deserialize the Supreme New York JSON but I am getting an error.
I used json2csharp.com to convert the Json into classes.
Then I summarised them all into one called items
namespace SUPBOTTESTING
{
public class items
{
public string name { get; set; }
public int id { get; set; }
public string image_url { get; set; }
public string image_url_hi { get; set; }
public int price { get; set; }
public int sale_price { get; set; }
public bool new_item { get; set; }
public int position { get; set; }
public string category_name { get; set; }
public int price_euro { get; set; }
public int sale_price_euro { get; set; }
}
}
using System;
using System.Net;
using System.Web.Script.Serialization;
namespace SUPBOTTESTING
{
class Program
{
public static void Main()
{
{
string shop_json = new WebClient().DownloadString("https://www.supremenewyork.com/mobile_stock.json");
JavaScriptSerializer shop_object = new JavaScriptSerializer();
items[] shirt_stock = shop_object.Deserialize<items[]>(shop_json);
Console.WriteLine(shirt_stock[1]);
}
}
}
}
I am getting the error:
Default constructor not found for type SUPBOTTESTING.items[]
Ok here is the solution. You have the correct idea but you need to understand the structure of your Json data.
You are deserializing it into an array of Object whereas your Json data returned itself is not an Array or a List. It contains child nodes that are an array so you need to structure your Object accordingly to get a successful breakdown of data.
Here I have used Newtonsoft to deserialise the Json data into an Object.
I have tested the code and it returns a list of Shirts
static void Main(string[] args)
{
var shop_json = new WebClient().DownloadString("https://www.supremenewyork.com/mobile_stock.json");
var shirt_stock = JsonConvert.DeserializeObject<StockObject>(shop_json);
// Picking shirts to demonstrate how to display values for all shirts
var shirts = shirt_stock.products_and_categories.Shirts;
foreach (var shirt in shirts)
{
var shirtBuilder = new StringBuilder();
shirtBuilder.AppendLine($"Name: {shirt.name}");
shirtBuilder.AppendLine($"ID: {shirt.id.ToString()}");
shirtBuilder.AppendLine($"New Item: {shirt.new_item.ToString()}");
shirtBuilder.AppendLine($"Category Name: {shirt.category_name}");
Console.WriteLine(shirtBuilder);
}
}
public class StockObject
{
public ProductsCats Products_and_categories { get; set; }
}
public class ProductsCats
{
public Details[] Shirts { get; set; }
public Details[] Bags { get; set; }
public Details[] Accessories { get; set; }
public Details[] Pants { get; set; }
public Details[] Jackets { get; set; }
public Details[] Skates { get; set; }
public Details[] Hats { get; set;}
public Details[] Sweatshirts { get; set;}
[JsonProperty("Tops/Sweaters")]
public Details[] TopsSweaters { get;set;}
public Details[] New { get; set; }
}
public class Details
{
public string name { get; set; }
public int id { get; set; }
public string image_url { get; set; }
public string image_url_hi { get; set; }
public int price { get; set; }
public int sale_price { get; set; }
public bool new_item { get; set; }
public int position { get; set; }
public string category_name { get; set; }
public int price_euro { get; set; }
public int sale_price_euro { get; set; }
}
You see what I have done here?
So your Json data contains a parent node products_and_categories and its child node contains an array of Shirts which is what you are after?
StockObject class contains the Parent property called Products_and_categories of type object ProductsCats.
ProductsCats Object contains the property Shirts of type Details which is an array and will be used during the deserialising process.
Hope this helps?
Well you do not need to specify a default constructor. What is wrong is, i think you didn't check the json data properly. Because your items class is not in the first level of json. You need to create a couple of classes to be more accurate on deserializing.
First of all you need to know that this json file has a lot of bad-smells and bad-practices on it.
Note that you need to install Newtonsoft.Json before going further. It is much more convenient way to deserialize a json into C# classes.
Yet, i wrote a proper way of deserializing it:
public class BaseItem
{
public string Name { get; set; }
public int Id { get; set; }
public string Image_url { get; set; }
public string Image_url_hi { get; set; }
public int Price { get; set; }
public int Sale_price { get; set; }
public bool New_item { get; set; }
public int Position { get; set; }
public string Category_name { get; set; }
public int Price_euro { get; set; }
public int Sale_price_euro { get; set; }
}
public class Shirt : BaseItem { }
public class Bag : BaseItem { }
public class Accessory : BaseItem { }
public class Pant : BaseItem { }
public class Jacket : BaseItem { }
public class Skate : BaseItem { }
public class Hat : BaseItem { }
public class Sweatshirt : BaseItem { }
public class TopsSweater : BaseItem { }
public class New : BaseItem { }
public class RootObject
{
public List<object> Unique_image_url_prefixes { get; set; }
public ProductsAndCategories Products_and_categories { get; set; }
public string Release_date { get; set; }
public string Release_week { get; set; }
}
public class ProductsAndCategories
{
public List<Shirt> Shirts { get; set; }
public List<Bag> Bags { get; set; }
public List<Accessory> Accessories { get; set; }
public List<Pant> Pants { get; set; }
public List<Jacket> Jackets { get; set; }
public List<Skate> Skate { get; set; }
public List<Hat> Hats { get; set; }
public List<Sweatshirt> Sweatshirts { get; set; }
[JsonProperty("Tops/Sweaters")]
public List<TopsSweater> TopsSweaters { get; set; }
public List<New> New { get; set; }
}
First of all, all of your items are have the same properties on them, yet, they all marked as different properties. So that, i created a BaseItem class and other empty classes which are inherited from that.
Also you need other 2 classes -which are RootObject and ProductsAndCategories- to provide data on them. Note that there is a JsonProperty("blabla") on the TopsSweaters property. Because, in json file it is Tops/Sweaters, and you can not use that name on a C# property. That is the attribute for using that kind of different property names.
Then you can populate your object like this:
static void Main(string[] args)
{
var jsonData = "https://www.supremenewyork.com/mobile_stock.json";
string shopJson = new WebClient().DownloadString(jsonData);
RootObject shirtStock = JsonConvert.DeserializeObject<RootObject>(shopJson); //All json data is in this variable
Console.WriteLine(shirtStock.Products_and_categories.Shirts[1]);
}
Your problem is that youre using a class to load the JSON data in, where you should use a struct, alternatively you can also create a constructor that takes no arguments and sets all variables to default values, which is a lot of work so just replace class with struct:
public struct Items
{
public string Name { get; set; }
public int Id { get; set; }
public string Image_Url { get; set; }
public string Image_Url_Hi { get; set; }
public int Price { get; set; }
public int Sale_Price { get; set; }
public bool New_item { get; set; }
public int Position { get; set; }
public string Category_Name { get; set; }
public int Price_Euro { get; set; }
public int Sale_Price_Euro { get; set; }
}
Also please stick to C# naming conventions, you should be able to do this since most JSON parsers are case insensitive by default.
Some more info: A class doesnt really has a proper default constructor if you dont define one, where as a struct always has a default constructor, so when the JSON parser wants to init your class it cant because a default constructor isnt definded.
static void Main(string[] args)
{
string shop_json = new WebClient().DownloadString("https://www.supremenewyork.com/mobile_stock.json");
JavaScriptSerializer shop_object = new JavaScriptSerializer();
var shirt_stock = shop_object.Deserialize<NewYarkItems>(shop_json);
var v = shirt_stock;
}
public class NewYarkItems
{
public dynamic unique_image_url_prefixes { get; set; }
public products_and_categories products_And_Categories { get; set; }
public string release_date { get; set; }
public string release_week { get; set; }
}
public class products_and_categories
{
public List<items> Jackets { get; set; }
}
public class items
{
public string name { get; set; }
public int id { get; set; }
public string image_url { get; set; }
public string image_url_hi { get; set; }
public int price { get; set; }
public int sale_price { get; set; }
public bool new_item { get; set; }
public int position { get; set; }
public string category_name { get; set; }
public int price_euro { get; set; }
public int sale_price_euro { get; set; }
}
I am having issues deserializing a nested JSON array from the Genius lyric website API. I formulated the object using http://json2csharp.com. When I deserialize the object, I am unable to access the properties inside of the class, which wasn't entirely unexpected, I am just not sure how to properly design an actual solution to the problem. The JSON object conversions work fine when they are not nested.
What would be the best way to go about handling this?
Here is the conversion code:
string test = await G.SearchGeniusASync(textBox1.Text);
var data = JsonConvert.DeserializeObject<GeniusApiObject>(test);
Here is my class:
class GeniusApiObject
{
public class Meta
{
public int status { get; set; }
}
public class Stats
{
public bool hot { get; set; }
public int unreviewed_annotations { get; set; }
public int concurrents { get; set; }
public int pageviews { get; set; }
}
public class PrimaryArtist
{
public string api_path { get; set; }
public string header_image_url { get; set; }
public int id { get; set; }
public string image_url { get; set; }
public bool is_meme_verified { get; set; }
public bool is_verified { get; set; }
public string name { get; set; }
public string url { get; set; }
public int iq { get; set; }
}
public class Result
{
public int annotation_count { get; set; }
public string api_path { get; set; }
public string full_title { get; set; }
public string header_image_thumbnail_url { get; set; }
public string header_image_url { get; set; }
public int id { get; set; }
public int lyrics_owner_id { get; set; }
public string lyrics_state { get; set; }
public string path { get; set; }
public int? pyongs_count { get; set; }
public string song_art_image_thumbnail_url { get; set; }
public Stats stats { get; set; }
public string title { get; set; }
public string title_with_featured { get; set; }
public string url { get; set; }
public PrimaryArtist primary_artist { get; set; }
}
public class Hit
{
public List<object> highlights { get; set; }
public string index { get; set; }
public string type { get; set; }
public Result result { get; set; }
}
public class Response
{
public List<Hit> hits { get; set; }
}
public class RootObject
{
public Meta meta { get; set; }
public Response response { get; set; }
}
}
This is the source for the SearchGeniusASync method in case it is helpful:
public async Task<string>SearchGeniusASync(string searchParameter)
{
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", clientAccessToken);
var result = await httpClient.GetAsync(new Uri("https://api.genius.com/search?q=" + searchParameter), HttpCompletionOption.ResponseContentRead);
var data = await result.Content.ReadAsStringAsync();
return data;
}
This is the scope I am given access to:
https://i.imgur.com/9mZMvfp.png
Here's a sample JSON request in plaintext:
https://pastebin.com/iA8dQafW
GeniusApiObject is not needed in the code, but I'll leave it in just because it helps organize things (may be that something else also has a RootObject from the auto-generator).
The problem is that you are trying to deserialize to what is just an empty class, the class itself has no properties, so you can't deserialize to it. You need to deserialize to the GeniusApiObject.RootObject.
var data = JsonConvert.DeserializeObject<GeniusApiObject.RootObject>(test);
Will deserialize to the .RootObject subclass. This is verified working:
Where I'm using File.ReadAllText("test.json") to load the example API data provided.
Here is a .NET Fiddle showing it working (without the root object and only one song in the response). Thanks to #maccttura.
I have the following Json format returned from a WebAPI. Can you guys help to deserialize please?.
{
"#odata.context":"http://....... ","value":[
**{
"RecordNumber":"LDxxxx","RecordType":"Loan","PropertyAddress":{ "Address1":"601 xxxx","Address2":null,"Zip":"99999","City":"abc","State":"ab","County":"abcd" }
,"Summary":{ "BorrowerName":null,"ProductCode":null,"Status":"Not Registered" }
}**,{
"RecordNumber":"LDxxxx","RecordType":"Loan","PropertyAddress":{ "Address1":"601 xxxx","Address2":null,"Zip":"99999","City":"abc","State":"ab","County":"abcd" }
,"Summary":{ "BorrowerName":null,"ProductCode":null,"Status":"Not Registered" }
},
….]
}
I need what's in the value element. The bold is what is repeated in the return from API. I created a class that matches the description as below.
public class RootObject
{
[JsonProperty(PropertyName = "RecordNumber")]
public string RecordNumber { get; set; }
[JsonProperty(PropertyName = "RecordType")]
public string RecordType { get; set; }
[JsonProperty(PropertyName = "PropertyAddress")]
public PropertyAddress PropertyAddress { get; set; }
[JsonProperty(PropertyName = "Summary")]
public Summary Summary { get; set; }
}
Was able to skip the first record in the Json array using the following, got the "Value" part....but have not been successful in retrieving the "Value" object
var dict = JsonConvert.DeserializeObject<Dictionary<string, object>>(forecast);
foreach (var kv in dict.Skip(1))
{
JArray jsonVal = JArray.Parse(kv.Value.ToString());
}
Appreciate your help.
Satya
You can deserialize to concrete classes (with the help of http://json2csharp.com/)
var result = JsonConvert.DeserializeObject<SOTest.Result>(json);
public class SOTest
{
public class PropertyAddress
{
public string Address1 { get; set; }
public object Address2 { get; set; }
public string Zip { get; set; }
public string City { get; set; }
public string State { get; set; }
public string County { get; set; }
}
public class Summary
{
public object BorrowerName { get; set; }
public object ProductCode { get; set; }
public string Status { get; set; }
}
public class Value
{
public string RecordNumber { get; set; }
public string RecordType { get; set; }
public PropertyAddress PropertyAddress { get; set; }
public Summary Summary { get; set; }
}
public class Result
{
[JsonProperty("#odata.context")]
public string Context { get; set; }
public List<Value> Value { get; set; }
}
}