Creating datamodel from JSON - c#

I am working on a winform application that is going to communicate with a webstore API. When I try to get all products from the webstore they present me with the following JSON:
{
"code":200,
"data":{
"product_data":{
"122":{
"products_id":"122",
"products_name":"Camilla armchair",
"products_model":"",
"products_url":"http:\/\/mystore-demo.no\/products\/camilla-armchair",
"products_url_identifier":"camilla-armchair",
"products_sort_order":"0",
"products_quantity":"0",
"products_weight":"0",
"products_status":"1",
"products_price_ex_tax":"249.0000",
"products_tax_percentage":"25",
"products_description":"Beskrivelse Camilla armchair",
"products_date_added":"2011-10-12 15:32:06",
"products_last_modified":"2011-10-12 15:32:06",
"products_brand_name":"",
"products_brand_id":"0",
"products_categories":[
"42",
"44"
],
"products_attributes":[
],
"products_tabs":[
],
"products_images":[
"http:\/\/mystore-demo.no\/users\/demo_mystore_no\/images\/122_Camilla_armchair_1.jpg"
],
"products_index": "2"
},
"123":{
"products_id":"123",
"products_name":"Egg Chair",
"products_model":"",
"products_url":"http:\/\/mystore-demo.no\/products\/egg-chair",
"products_url_identifier":"egg-chair",
"products_sort_order":"0",
"products_quantity":"0",
"products_weight":"0",
"products_status":"1",
"products_price_ex_tax":"2999.0000",
"products_tax_percentage":"25",
"products_description":"Beskrivelse Egg Chair",
"products_date_added":"2011-10-12 15:33:27",
"products_last_modified":"2011-10-12 15:33:27",
"products_brand_name":"",
"products_brand_id":"0",
"products_categories":[
"42"
],
"products_attributes":[
],
"products_tabs":[
],
"products_images":[
"http:\/\/mystore-demo.no\/users\/demo_mystore_no\/images\/123_Egg_Chair_1.jpg"
],
"products_index": "3"
},
"121":{
"products_id":"121",
"products_name":"Round chair",
"products_model":"",
"products_url":"http:\/\/mystore-demo.no\/products\/round-chair",
"products_url_identifier":"round-chair",
"products_sort_order":"0",
"products_quantity":"0",
"products_weight":"0",
"products_status":"1",
"products_price_ex_tax":"1599.0000",
"products_tax_percentage":"25",
"products_description":"Beskrivelse Round Chair",
"products_date_added":"2011-10-11 10:43:42",
"products_last_modified":"2011-10-11 10:43:42",
"products_brand_name":"",
"products_brand_id":"0",
"products_categories":[
"42"
],
"products_attributes":[
],
"products_tabs":[
],
"products_images":[
"http:\/\/mystore-demo.no\/users\/demo_mystore_no\/images\/121_Round_chair_1.jpg"
]
,
"products_index": "1"
}
},
"product_count_total":3
}
}
I have created a MyStoreResponse class (datamodel) that looks like this:
using Newtonsoft.Json;
namespace MyStoreSync.Models
{
public class Product
{
[JsonProperty("products_id")]
public string ProductsId { get; set; }
[JsonProperty("products_name")]
public string ProductsName { get; set; }
[JsonProperty("products_model")]
public string ProductsModel { get; set; }
[JsonProperty("products_url")]
public string ProductsUrl { get; set; }
[JsonProperty("products_url_identifier")]
public string ProductsUrlIdentifier { get; set; }
[JsonProperty("products_sort_order")]
public string ProductsSortOrder { get; set; }
[JsonProperty("products_quantity")]
public string ProductsQuantity { get; set; }
[JsonProperty("products_weight")]
public string ProductsWeight { get; set; }
[JsonProperty("products_status")]
public string ProductsStatus { get; set; }
[JsonProperty("products_price_ex_tax")]
public string ProductsPriceExTax { get; set; }
[JsonProperty("products_tax_percentage")]
public string ProductsTaxPercentage { get; set; }
[JsonProperty("products_description")]
public string ProductsDescription { get; set; }
[JsonProperty("products_date_added")]
public string ProductsDateAdded { get; set; }
[JsonProperty("products_last_modified")]
public string ProductsLastModified { get; set; }
[JsonProperty("products_brand_name")]
public string ProductsBrandName { get; set; }
[JsonProperty("products_brand_id")]
public string ProductsBrandId { get; set; }
[JsonProperty("products_categories")]
public string[] ProductsCategories { get; set; }
[JsonProperty("products_attributes")]
public object[] ProductsAttributes { get; set; }
[JsonProperty("products_tabs")]
public object[] ProductsTabs { get; set; }
[JsonProperty("products_images")]
public string[] ProductsImages { get; set; }
[JsonProperty("products_index")]
public string ProductsIndex { get; set; }
}
public class ProductData
{
[JsonProperty("Product")]
public Product Product { get; set; }
}
public class Data
{
[JsonProperty("product_data")]
public ProductData ProductData { get; set; }
[JsonProperty("product_count_total")]
public int ProductCountTotal { get; set; }
}
public class MyStoreResponse
{
[JsonProperty("code")]
public int Code { get; set; }
[JsonProperty("data")]
public Data Data { get; set; }
}
}
I get the correct ProductCountTotal, but Product is always null. Can anyone with more knowledege about parsing JSON help me?

You need to make the ProductData property be a dictionary:
public class Data
{
[JsonProperty("product_data")]
public Dictionary<string, Product> ProductData { get; set; }
[JsonProperty("product_count_total")]
public int ProductCountTotal { get; set; }
}
The ProductData class is unnecessary. The JSON property names "122", "123" and "121" become the dictionary keys, and the associated Product the value. See Serialize a Dictionary.

You are having this problem because "product" isn't a key in the json returned, in your ProductData class the key is named "product", but "121", "122" and "123" represent products...
You could do the Product serialization like this:
foreach(var x in productDataInstance)
{
Product p = JsonConvert.Deserialize(x);
}
Also, I think ProductData should have a list of Products.
public class ProductData
{
public List<Product> products = new List<Products>();
}
We'll now have:
foreach(var x in productDataInstance)
{
Product p = JsonConvert.Deserialize(x);
productDataInstance.products.Add(p);
}
NB productDataInstance is ProductData in your Data class.
Hope this helped.

Related

Deserialize JSON to List

I have this Json:
{
"trades": [
{
"id": "4004",
"instrument": "EUR_USD",
"price": "1.08938",
"openTime": "2020-02-26T12:15:32.309973340Z",
"initialUnits": "1",
"initialMarginRequired": "0.0363",
"state": "OPEN",
"currentUnits": "1",
"realizedPL": "0.0000",
"financing": "0.0000",
"dividendAdjustment": "0.0000",
"unrealizedPL": "-0.0026",
"marginUsed": "0.0362",
"takeProfitOrder": {
"id": "4005",
"createTime": "2020-02-26T12:15:32.309973340Z",
"type": "TAKE_PROFIT",
"tradeID": "4004",
"price": "1.09099",
"timeInForce": "GTC",
"triggerCondition": "DEFAULT",
"state": "PENDING"
}
}
],
"lastTransactionID": "4010"
}
And Classes:
public class TakeProfitOrder
{
public string id { get; set; }
public string createTime { get; set; }
public string type { get; set; }
public string tradeID { get; set; }
public string price { get; set; }
public string timeInForce { get; set; }
public string triggerCondition { get; set; }
public string state { get; set; }
}
public class Trade
{
public string id { get; set; }
public string instrument { get; set; }
public string price { get; set; }
public string openTime { get; set; }
public string initialUnits { get; set; }
public string initialMarginRequired { get; set; }
public string state { get; set; }
public string currentUnits { get; set; }
public string realizedPL { get; set; }
public string financing { get; set; }
public string dividendAdjustment { get; set; }
public string unrealizedPL { get; set; }
public string marginUsed { get; set; }
public TakeProfitOrder takeProfitOrder { get; set; }
}
public class RootObject
{
public List<Trade> trades { get; set; }
public string lastTransactionID { get; set; }
}
I deserialize with :
var result = JsonConvert.DeserializeObject<RootObject>(Json);
var price = result.trades.Select(p => p.price).ToList();
price.ForEach(Console.WriteLine);
It works. I can access "price" in "trades", but I do not know how to access the "price" in "takeProfitOrder". I need the value of "price" from "takeProfitOrder" in to a list. I am sure it is something very simple but I cannot figure out how to do it, even after looking at some similar examples.
Can somebody please help me?
It's simple
result.trades.Select(p => p.takeProfitOrder.price)
You should understand better from this example
foreach (Trade trade in result.trades)
{
TakeProfitOrder takeProfitOrder = trade.takeProfitOrder;
Console.WriteLine(takeProfitOrder.price);
}

Nested Json Convert to Class C#

I am needing the first item in the array of object b in this json.
{
"error":[],
"result":{
"XXRPXXBT":{
"a":[
"0.000084280",
"123",
"123.000"
],
"b":[
"0.000084120",
"24263",
"24263.000"
],
"c":[
"0.000084140",
"772.40225814"
],
"v":[
"1002684.00590349",
"1081301.61838716"
],
"p":[
"0.000085783",
"0.000085799"
],
"t":[
731,
866
],
"l":[
"0.000083420",
"0.000083420"
],
"h":[
"0.000086610",
"0.000086720"
],
"o":"0.000086300"
}
}
}
Could someone please tell me how the class properties would look to get to that level. I have tried a json deserialization with a string for result but it fails on the convert.
I don't have to have all the values just the first item in the b array.
This is what I had done:
TestResponse deserializedKrakenResult = JsonConvert.DeserializeObject<TestResponse>(json);
public class TestResponse
{
public string[] result { get; set; }
}
and
public class TestResponse
{
public object[] result { get; set; }
}
and
public class TestResponse
{
public string result { get; set; }
}
These were done just to get it to parse.
Open Visual Studio
Open Edit => Click Paste Special => Click Paste Json as Classes
Here is the result:
public class Rootobject
{
public object[] error { get; set; }
public Result result { get; set; }
}
public class Result
{
public XXRPXXBT XXRPXXBT { get; set; }
}
public class XXRPXXBT
{
public string[] a { get; set; }
public string[] b { get; set; }
public string[] c { get; set; }
public string[] v { get; set; }
public string[] p { get; set; }
public int[] t { get; set; }
public string[] l { get; set; }
public string[] h { get; set; }
public string o { get; set; }
}

Parsing JSON with LINQ into List of Objects

I'm a little confused on the best way to parse the following JSON structure.
{
"featured": {
"id": 15,
"title": "media 1 -> 7",
"description": "test1",
"short_description": "test1",
"rating_avg": 0.0,
"image": "//d25xdrj7gd7wz1.cloudfront.net/covers/1603/1452024324.jpg"
},
"categories": [
{
"id": 1,
"title": "category 0",
"description": null,
"position": 0,
"media": [
{
"id": 1,
"title": "media 0 -> 0",
"description": "test1",
"short_description": "test1",
"rating_avg": 0.0,
"image": "//d25xdrj7gd7wz1.cloudfront.net/covers/1603/1452024324.jpg",
"category_media": {
"position": 0,
"category_id": 1,
"media_id": 1,
"id": 1
}
}, ...
Basically I have an array of categories which contains an array of medias (the featured is for something else)
I am looking to return List and the Category object contains a List
and I created some models:
public class Category
{
public string Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public List<Media> MediaList { get; set; }
}
public class Media
{
public string Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string ShortDescription { get; set; }
public string Image { get; set; }
}
..and I am supposed to use Newtonsoft?
I looked at the following example: Deserializing Partial JSON Fragments but I would think I don't need to convert from JToken -> Category ... etc. In other words, I would think it would be easy to just return my List.
I'm new to LINQ (I come from a python background) so I'm getting to know C#
Use This as your Model
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public partial class JsonModel
{
[JsonProperty("featured")]
public Featured Featured { get; set; }
[JsonProperty("categories")]
public List<Category> Categories { get; set; }
}
public partial class Category
{
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("description")]
public object Description { get; set; }
[JsonProperty("position")]
public long Position { get; set; }
[JsonProperty("media")]
public List<Featured> Media { get; set; }
}
public partial class Featured
{
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("short_description")]
public string ShortDescription { get; set; }
[JsonProperty("rating_avg")]
public long RatingAvg { get; set; }
[JsonProperty("image")]
public string Image { get; set; }
[JsonProperty("category_media", NullValueHandling = NullValueHandling.Ignore)]
public CategoryMedia CategoryMedia { get; set; }
}
public partial class CategoryMedia
{
[JsonProperty("position")]
public long Position { get; set; }
[JsonProperty("category_id")]
public long CategoryId { get; set; }
[JsonProperty("media_id")]
public long MediaId { get; set; }
[JsonProperty("id")]
public long Id { get; set; }
}
}
Then do this in your Class:
var info = JsonConvert.DeserializeObject<JsonModel>(json);
var featured = info.Featured;
var categories = info.Categories;
You don't need LINQ in this case unless you want to change the data structure. To parse json file to list you have to create a class that matches a structure of your file, like:
class DataModel
{
public Featured Featured { get; set; }
public List<Category> Categories { get;set; }
}
Also, please pay attention that you need to use attribute [JsonProperty(PropertyName="fieldName")] if property name in json is different from property name in class.
And finally, to parse the data use the following row:
var data = JsonConvert.DeserializeObject<DataModel>(jsonString);
Act as follow:
Update your models with:
public class Category
{
public string Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public List<Media> Media { get; set; }
}
public class Media
{
public string Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string ShortDescription { get; set; }
public string Image { get; set; }
}
public class Featured
{
public string Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Short_Description { get; set; }
}
And then make a model same as your JSON structure:
public class YOUR_MODEL
{
public Featured Featured { get; set; }
public List<Category> Categories { get;set; }
}
And then Descrilize your JSON to your object:
YOUR_MODELresults = JsonConvert.DeserializeObject<YOUR_MODEL>(YOUR_JSON);
To get your model you can use tool like :
https://jsonutils.com/ or http://json2csharp.com/
In case of need you can also validate json syntax with : https://jsonlint.com/ to get detailed errors.
With a slightly modified version of your example, I get :
public class CategoryMedia
{
public int position { get; set; }
public int category_id { get; set; }
public int media_id { get; set; }
public int id { get; set; }
}
public class Medium
{
public int id { get; set; }
public string title { get; set; }
public string description { get; set; }
public string short_description { get; set; }
public double rating_avg { get; set; }
public string image { get; set; }
public CategoryMedia category_media { get; set; }
}
public class Category
{
public int id { get; set; }
public string title { get; set; }
public object description { get; set; }
public int position { get; set; }
public IList<Medium> media { get; set; }
}
public class Featured
{
public int id { get; set; }
public string title { get; set; }
public string description { get; set; }
public string short_description { get; set; }
public double rating_avg { get; set; }
public string image { get; set; }
public IList<Category> categories { get; set; }
}
public class Example
{
public Featured featured { get; set; }
}
It spares a lot of time for creating models and it allows you to verify that you don't have typos in field names.
With this, you just have to deserialize your JSON sample to "Example" class, using the library of your choice. Newtonsoft Json is a very efficient classical !
Newtonsoft is the standard for doing work like this. So lets look at the best way to do this. First lets start with your json format and fix it so you can use the online tools available to create a good model structure:
[
{
"featured": {
"id": 15,
"title": "media 1 -> 7",
"description": "test1",
"short_description": "test1",
"rating_avg": 0.0,
"image": "//d25xdrj7gd7wz1.cloudfront.net/covers/1603/1452024324.jpg"
},
"categories": [
{
"id": 1,
"title": "category 0",
"description": null,
"position": 0,
"media": [
{
"id": 1,
"title": "media 0 -> 0",
"description": "test1",
"short_description": "test1",
"rating_avg": 0.0,
"image": "//d25xdrj7gd7wz1.cloudfront.net/covers/1603/1452024324.jpg",
"category_media": {
"position": 0,
"category_id": 1,
"media_id": 1,
"id": 1
}
}
]
}
]
}
]
Now if you plug that into http://json2csharp.com/, it will output a good model structure:
public class Featured
{
public int id { get; set; }
public string title { get; set; }
public string description { get; set; }
public string short_description { get; set; }
public double rating_avg { get; set; }
public string image { get; set; }
}
public class CategoryMedia
{
public int position { get; set; }
public int category_id { get; set; }
public int media_id { get; set; }
public int id { get; set; }
}
public class Medium
{
public int id { get; set; }
public string title { get; set; }
public string description { get; set; }
public string short_description { get; set; }
public double rating_avg { get; set; }
public string image { get; set; }
public CategoryMedia category_media { get; set; }
}
public class Category
{
public int id { get; set; }
public string title { get; set; }
public object description { get; set; }
public int position { get; set; }
public List<Medium> media { get; set; }
}
public class RootObject
{
public Featured featured { get; set; }
public List<Category> categories { get; set; }
}
Feel free to rename RootObject So now lets look are how you can deserialize your json into your model objects using Newtonsoft:
Firstly you need to get your json file into a string format, so lets say its a file on your computer or in your project, there is many ways to retrieve it, either using Assembly, or Directory methods. Once you have access to your json file, read out the contents and then using Newtonsoft method for deserialising:
var myString = File.ReadAllText(path)
var myObject = JsonConvert.DeserializeObject<RootObject>(myString);
And thats it:P

Serializing Json to c# Class throwing error

I have a JSON returning from web like this
{
"data": {
"normal_customer": {
"0": {
"id": 1,
"name": "ALPHY"
}
},
"1": {
"id": 2,
"name": "STEVEN"
}
},
"luxury_customer": {
"3": {
"id": 8,
"name": "DEV"
}
}
}
}
I have created c# classes
public class StandardCustomers
{
public List<CustomersDetails> Customers_Details { get; set; }
}
public class CustomersDetails
{
[JsonProperty("id")]
public int id { get; set; }
[JsonProperty("name")]
public string name { get; set; }
public class LuxuryCustomers
{
public List<CustomersDetails> Customers_Details { get; set; }
}
public class Data
{
public StandardCustomers standard_Customers { get; set; }
public LuxuryCustomers luxury_Customers { get; set; }
}
public class RootObject
{
public Data data { get; set; }
}
}
When I use deserialize the response from the website using below c# code
var result1 = JsonConvert.DeserializeObject<Data>(response);
but result1.luxury_customers contains customerdetails which is null.
As suggested by #hellostone, I have modified to rootdata, then also
result1.luxury_customers contains customerdetails is null.
Any idea how to deserialize to c# class
When we pasted Json to visual studio, it generated classes as below
public class Rootobject
{
public Data data { get; set; }
}
public class Data
{
public Standard_Customers standard_Customers { get; set; }
public Luxury_Customers luxury_Customers { get; set; }
}
public class Standard_Customers
{
public _0 _0 { get; set; }
public _1 _1 { get; set; }
public _2 _2 { get; set; }
public _4 _4 { get; set; }
public _5 _5 { get; set; }
}
public class _0
{
public int id { get; set; }
public string name { get; set; }
}
individual classes are generated in standard customers , can we use list for this
I guess the problem is that index in luxury_customers starting not from zero. Try to use Dictionary<string,CustomersDetails> in LuxuryCustomers instead List<CustomersDetails>.
I've managed to deserialize Json with this classes:
public class CustomersDetails
{
[JsonProperty("id")]
public int id { get; set; }
[JsonProperty("name")]
public string name { get; set; }
}
public class Data
{
public Dictionary<string, CustomersDetails> normal_customer { get; set; }
public Dictionary<string,CustomersDetails> luxury_customer { get; set; }
}
public class RootObject
{
public Data data { get; set; }
}
Deserialization code:
var result = JsonConvert.DeserializeObject<RootObject>(text);
P.S. I've remove one closing bracket after "ALPHY" element, to make Json valid, I hope it was typo and you're getting valid Json.
Your json string doesn't match with your defined classes. Your Json string should look like this if you want to preserve your class structure:
{
"data":{
"standard_Customers":{
"Customers_Details":[
{
"id":1,
"name":"ALPHY"
},
{
"id":2,
"name":"STEVEN"
}
]
},
"luxury_Customers":{
"Customers_Details":[
{
"id":8,
"name":"DEV"
}
]
}
}
}
Pay attention to the square brackets at the "Customers_Details" attribute.
Then the:
var result1 = JsonConvert.DeserializeObject<RootObject>(response);
call, will give you the right object back and it shouldn't be null, when using your class structure:
public class StandardCustomers
{
public List<CustomersDetails> Customers_Details { get; set; }
}
public class CustomersDetails
{
[JsonProperty("id")]
public int id { get; set; }
[JsonProperty("name")]
public string name { get; set; }
}
public class LuxuryCustomers
{
public List<CustomersDetails> Customers_Details { get; set; }
}
public class Data
{
public StandardCustomers standard_Customers { get; set; }
public LuxuryCustomers luxury_Customers { get; set; }
}
public class RootObject
{
public Data data { get; set; }
}

Converting Json code to C# (numbers as keys)

I get some json code from web services in Windows Phone 8. I generate my entities class thanks to the site json2csharp (http://json2csharp.com/). But there is a web service that has strange json code, like this. There is numbering as keys (0,1,2):
{
"service": "MainMapService",
"func": "getPlacesByAxes",
"result": {
"0": {
"id": "13478",
"date": "0",
"id_cat": "1",
"id_cat_sub": "0",
"id_user": "0",
},
"2": {
"id": "23272",
"date": "0",
"id_cat": "1",
"id_cat_sub": "0",
"id_user": "667"
},
"1": {
"id": "21473",
"date": "0",
"id_cat": "1",
"id_cat_sub": "0",
"id_user": "0"
}
},
"args": [
"1",
"50.8",
"4.5",
"1"
]
}
And json2csharp generates classes like this... Each class for a number:
public class __invalid_type__0
{
public string id { get; set; }
public string date { get; set; }
public string id_cat { get; set; }
public string id_cat_sub { get; set; }
public string id_user { get; set; }
}
public class __invalid_type__2
{
public string id { get; set; }
public string date { get; set; }
public string id_cat { get; set; }
public string id_cat_sub { get; set; }
public string id_user { get; set; }
}
public class __invalid_type__1
{
public string id { get; set; }
public string date { get; set; }
public string id_cat { get; set; }
public string id_cat_sub { get; set; }
public string id_user { get; set; }
}
public class Result
{
public __invalid_type__0 __invalid_name__0 { get; set; }
public __invalid_type__2 __invalid_name__2 { get; set; }
public __invalid_type__1 __invalid_name__1 { get; set; }
}
public class RootObject
{
public string service { get; set; }
public string func { get; set; }
public Result result { get; set; }
public List<string> args { get; set; }
}
So, the problem comes from the numbering keys and there may be several numbers. Do you know how can I resolve this? I can't change the Json code...
Thank you in advance
This is far from elegant, but give it a try.
So, what is my idea:
I have created two classes
RootObject helper
public class YourJsonClass
{
public string service { get; set; }
public string func { get; set; }
public dynamic result { get; set; }
public string[] args { get; set; }
}
result helper
public class Item
{
public string id { get; set; }
public string date { get; set; }
public string id_cat { get; set; }
public string id_cat_sub { get; set; }
public string id_user { get; set; }
}
I'm using newtonsoft json
var m_res = JsonConvert.DeserializeObject<YourJsonClass>(YourJsonResponce);
foreach (dynamic numb in m_res.result)
{
string m_name = numb.Name; // it will be "1", "0" or whatever
string h = numb.Value.ToString();
var m_value = JsonConvert.DeserializeObject<Item>(h);
}
... indeed there are better ways, but i hope this will help (:

Categories