How to deserialize complex JSON string into Dataset in c#? - c#

Here is the JSON string that needs to be converted:
{
"b2b": [
{
"ctin": "37ABCDE9552F3Z4",
"inv": [
{
"inum": "S008400",
"idt": "09-04-2016",
"val": 861786.91,
"pos": "6",
"rchrg": "No",
"pro_ass": "Y",
"itms": [
{
"num": 1,
"itm_det": {
"ty": "S",
"hsn_sc": "H724",
"txval": 5589.87,
"irt": 0.0,
"iamt": 0.0,
"crt": 87.92,
"camt": 5.7947562568E8,
"srt": 86.56,
"samt": 50.74
}
},
{
"num": 2,
"itm_det": {
"ty": "S",
"hsn_sc": "H863",
"txval": 2509.27,
"irt": 0.0,
"iamt": 0.0,
"crt": 12.99,
"camt": 26144.48,
"srt": 31.81,
"samt": 276654.5
}
}
]
}
]
},
{
"ctin": "76ABCDE2148F9Z9",
"inv": [
{
"chksum": "AflJufPlFStqKBZ",
"inum": "S008400",
"idt": "24-11-2016",
"val": 729248.16,
"pos": "6",
"rchrg": "No",
"pro_ass": "Y",
"itms": [
{
"num": 1,
"itm_det": {
"ty": "S",
"hsn_sc": "S8590",
"txval": 8196.88,
"irt": 0.0,
"iamt": 0.0,
"crt": 42.44,
"camt": 202.86,
"srt": 40.99,
"samt": 0.02
}
},
{
"num": 2,
"itm_det": {
"ty": "S",
"hsn_sc": "H357",
"txval": 6760.14,
"irt": 0.0,
"iamt": 0.0,
"crt": 23.89,
"camt": 6.8214986738E8,
"srt": 60.95,
"samt": 0.03
}
}
]
}
]
}
]
}
I need the inner loop data as new table. ie the first table should contain 2 rows which should have "ctin" and "inv" in it. Similarly the second table should have the inum details and the third table should have the item details.

With json2charp you can easily generate C# classes for parsing from the JSON. For your data you can use:
public class ItmDet
{
public string ty { get; set; }
public string hsn_sc { get; set; }
public double txval { get; set; }
public double irt { get; set; }
public double iamt { get; set; }
public double crt { get; set; }
public double camt { get; set; }
public double srt { get; set; }
public double samt { get; set; }
}
public class Itm
{
public int num { get; set; }
public ItmDet itm_det { get; set; }
}
public class Inv
{
public string inum { get; set; }
public string idt { get; set; }
public double val { get; set; }
public string pos { get; set; }
public string rchrg { get; set; }
public string pro_ass { get; set; }
public List<Itm> itms { get; set; }
public string chksum { get; set; }
}
public class B2b
{
public string ctin { get; set; }
public List<Inv> inv { get; set; }
}
public class RootObject
{
public List<B2b> b2b { get; set; }
}
You can remove the properties you do not need. Parsing with JSON.NET is like
var data = JsonConvert.DeserializeObject<RootObject>(jsonString);

I suggest you follow the bellow steps:
Copy your JSON string
Go to Visual Studio and press this menu item: Edit > Paste Special > Paste JSON as classes
Enjoy the result!
Appropriate classes:
public class Rootobject
{
public B2b[] b2b { get; set; }
}
public class B2b
{
public string ctin { get; set; }
public Inv[] inv { get; set; }
}
public class Inv
{
public string inum { get; set; }
public string idt { get; set; }
public float val { get; set; }
public string pos { get; set; }
public string rchrg { get; set; }
public string pro_ass { get; set; }
public Itm[] itms { get; set; }
public string chksum { get; set; }
}
public class Itm
{
public int num { get; set; }
public Itm_Det itm_det { get; set; }
}
public class Itm_Det
{
public string ty { get; set; }
public string hsn_sc { get; set; }
public float txval { get; set; }
public float irt { get; set; }
public float iamt { get; set; }
public float crt { get; set; }
public float camt { get; set; }
public float srt { get; set; }
public float samt { get; set; }
}
Note: Also you can use some attributes like [DataContract(Name ="...")] over the classes and [DataMember(Name = "...")] over the properties to make some differents between C# and JSON property names.
You should replace ... with a name
Reference

Related

Value from deserialized JSON string is 0

I'm trying to get the amount of pieces belonging to a certain Lego set using the Brickset API (https://brickset.com/article/52664/api-version-3-documentation)
When writing the Json string to the console it displays the amount of pieces correct. Howeever after deserializing and then writing only the value of pieces to the console it displays 0. All other properties are also not displayed when written to the console.
Result after writing the Json string to the console
{"status":"success","matches":1,"sets":\[
{
"setID": 31844,
"number": "10293",
"numberVariant": 1,
"name": "Santa's Visit",
"year": 2021,
"theme": "Icons",
"themeGroup": "Model making",
"subtheme": "Winter Village Collection",
"category": "Normal",
"released": true,
"pieces": 1445,
"minifigs": 4,
"image": {
"thumbnailURL": "https://images.brickset.com/sets/small/10293-1.jpg",
"imageURL": "https://images.brickset.com/sets/images/10293-1.jpg"
},
"bricksetURL": "https://brickset.com/sets/10293-1",
"collection": {},
"collections": {
"ownedBy": 9350,
"wantedBy": 2307
},
"LEGOCom": {
"US": {
"retailPrice": 99.99,
"dateFirstAvailable": "2021-09-17T00:00:00Z"
},
"UK": {
"retailPrice": 89.99,
"dateFirstAvailable": "2021-09-17T00:00:00Z"
},
"CA": {
"retailPrice": 139.99,
"dateFirstAvailable": "2021-09-17T00:00:00Z"
},
"DE": {
"retailPrice": 99.99,
"dateFirstAvailable": "2021-09-17T00:00:00Z"
}
},
"rating": 4.3,
"reviewCount": 0,
"packagingType": "Box",
"availability": "LEGO exclusive",
"instructionsCount": 15,
"additionalImageCount": 13,
"ageRange": {
"min": 18
},
"dimensions": {
"height": 28.0,
"width": 47.9,
"depth": 8.7,
"weight": 1.656
},
"barcode": {
"EAN": "5702016914313"
},
"extendedData": {
"tags": \[
"Santa Claus|n",
"18 Plus",
"Baked Goods",
"Bedroom",
"Bird",
"Brick Built Tree",
"Brick Separator",
"Christmas",
"Christmas Tree",
"D2c",
"Fireplace",
"Furniture",
"House",
"Kitchen",
"Light Brick",
"Mail",
"Microscale",
"Musical",
"Rocket",
"Seasonal",
"Winter Village"
\]
},
"lastUpdated": "2022-10-03T08:24:39.49Z"
}
\]}
Main Code
class Program
{
static async Task Main(string[] args)
{
await askSetNumber();
}
private async Task GetPosts(string url)
{
HttpClient client = new HttpClient();
string response = await client.GetStringAsync(url);
Console.WriteLine(response);
var set = JsonConvert.DeserializeObject<Rootobject>(response);
Console.WriteLine(set.pieces);
}
static async Task askSetNumber()
{
Console.WriteLine("Please enter a setnumber: ");
string setNumber = "{'setNumber':'" + Console.ReadLine().ToString() + "-1'}";
string url = "https://brickset.com/api/v3.asmx/getSets?apiKey=[APIKey here]&userHash=&params=" + setNumber;
Console.WriteLine(url);
Program program = new Program();
await program.GetPosts(url);
}
}
I made all classes by Pasting the Json as classes, This is the class of the object I need the data off
public class Rootobject
{
public int setID { get; set; }
public string number { get; set; }
public int numberVariant { get; set; }
public string name { get; set; }
public int year { get; set; }
public string theme { get; set; }
public string themeGroup { get; set; }
public string subtheme { get; set; }
public string category { get; set; }
public bool released { get; set; }
public int pieces { get; set; }
public int minifigs { get; set; }
public Image image { get; set; }
public string bricksetURL { get; set; }
public Collection collection { get; set; }
public Collections collections { get; set; }
public Legocom LEGOCom { get; set; }
public float rating { get; set; }
public int reviewCount { get; set; }
public string packagingType { get; set; }
public string availability { get; set; }
public int instructionsCount { get; set; }
public int additionalImageCount { get; set; }
public Agerange ageRange { get; set; }
public Dimensions dimensions { get; set; }
public Barcode barcode { get; set; }
public Extendeddata extendedData { get; set; }
public DateTime lastUpdated { get; set; }
}
I tried the example from How to get some values from a JSON string in C#? but set.pieces keeps returning 0.
This is my first time trying this kind of stuff, but I am stuck on this part.
Rootobject does not contain the same information as the json string you outputted to the console (it also escapes square brackets for some reason), so you either need to specify the entire object or navigate the json tree to get the value you require.
This is not a particularly good or robust solution, but you could replace the var set portion of you code with:
JsonDocument doc = JsonDocument.Parse(response);
if (!doc.RootElement.TryGetProperty("sets", out JsonElement sets)) return;
foreach(var set in sets.EnumerateArray())
{
if (!set.TryGetProperty("pieces", out JsonElement pieces)) continue;
Console.WriteLine(pieces.GetInt32());
}
(You'll also need using System.Text.Json; rather than the newtonsoft one.)
you have you json at first,since you have some strange "/" chars, after this you have to fix your classes too
json=json.Replace("\\[","[").Replace("\\]","]");
Set set = JsonConvert.DeserializeObject<Set>(json);
public class Set
{
public string status { get; set; }
public int matches { get; set; }
public List<SetItem> sets { get; set; }
}
public class SetItem
{
public int setID { get; set; }
public string number { get; set; }
public int numberVariant { get; set; }
public string name { get; set; }
public int year { get; set; }
public string theme { get; set; }
public string themeGroup { get; set; }
public string subtheme { get; set; }
public string category { get; set; }
public bool released { get; set; }
public int pieces { get; set; }
public int minifigs { get; set; }
public Image image { get; set; }
public string bricksetURL { get; set; }
public Collection collection { get; set; }
public Collections collections { get; set; }
public LEGOCom LEGOCom { get; set; }
public double rating { get; set; }
public int reviewCount { get; set; }
public string packagingType { get; set; }
public string availability { get; set; }
public int instructionsCount { get; set; }
public int additionalImageCount { get; set; }
public AgeRange ageRange { get; set; }
public Dimensions dimensions { get; set; }
public Barcode barcode { get; set; }
public ExtendedData extendedData { get; set; }
public DateTime lastUpdated { get; set; }
}
public class LEGOCom
{
public Country US { get; set; }
public Country UK { get; set; }
public Country CA { get; set; }
public Country DE { get; set; }
}
public class AgeRange
{
public int min { get; set; }
}
public class Barcode
{
public string EAN { get; set; }
}
public class Country
{
public double retailPrice { get; set; }
public DateTime dateFirstAvailable { get; set; }
}
and maybe it make some sense to define LEGOCom as a Dictionary, if you have much more countries
public Dictionary<string,Country> LEGOCom { get; set; }

How do I parse Openweather One Call in C#?

I have successfully parsed Openweather's 'Current Weather Data' using Json, but I'm having a problem with 'One Call'. It returns the data arranged a little differently. I can pull out everything except the 'weather' list. The class I created for it returns null values.
{
"lat": 41.9585,
"lon": -78.1892,
"timezone": "America/New_York",
"timezone_offset": -14400,
"current": {
"dt": 1652559634,
"sunrise": 1652522008,
"sunset": 1652574293,
"temp": 74.53,
"feels_like": 75.11,
"pressure": 1014,
"humidity": 73,
"dew_point": 65.32,
"uvi": 2.37,
"clouds": 100,
"visibility": 10000,
"wind_speed": 7.47,
"wind_deg": 173,
"wind_gust": 10.63,
"weather": [
{
"id": 804,
"main": "Clouds",
"description": "overcast clouds",
"icon": "04d"
}
]
}
}
string url = string.Format("https://api.openweathermap.org/data/2.5/onecall?lat={0}&lon={1}&exclude=minutely,hourly,daily&appid={2}&units=imperial", 41.958496166, -78.18916591, APIKey);
string jason = web.DownloadString(url);
WeatherInfo.root info = JsonConvert.DeserializeObject<WeatherInfo.root>(jason);
public static class WeatherInfo
{
public class current
{
public double dt { get; set; }
public double sunrise { get; set; }
public double sunset { get; set; }
public double temp { get; set; }
public double pressure { get; set; }
public double humidity { get; set; }
public double dew_point { get; set; }
public double uvi { get; set; }
public double clouds { get; set; }
public double visibility { get; set; }
public double wind_speed { get; set; }
public double wind_deg { get; set; }
public double wind_gust { get; set; }
}
public class weather
{
public string main { get; set; }
public string description { get; set; }
public string icon { get; set; }
}
public class root
{
public current current { get; set; }
public List<weather> weather { get; set; }
}
}

Azure JSON Response Deserialization C#

My JSON Response is shown below,
[
{
"faceRectangle": {
"top": 214,
"left": 472,
"width": 450,
"height": 450
},
"faceAttributes": {
"age": 19.0,
"emotion": {
"anger": 0.0,
"contempt": 0.0,
"disgust": 0.0,
"fear": 0.0,
"happiness": 0.0,
"neutral": 0.996,
"sadness": 0.003,
"surprise": 0.001
}
}
}
]
My C# class is as follows:
public class Output
{
public List<FaceRectangle> FaceRectangles { get; set; }
public List<FaceAttribute> faceAttributes { get; set; }
}
public class FaceAttribute
{
public List<Emotion> Emotions { get; set; }
public int age { get; set; }
}
public class Emotion {
public float anger { get; set; }
public float contempt { get; set; }
public float disgust { get; set; }
public float fear { get; set; }
public float happiness { get; set; }
public float neutral { get; set; }
public float sadness { get; set; }
public float surprise { get; set; }
}
public class FaceRectangle
{
public int top { get; set; }
public int left { get; set; }
public int width { get; set; }
public int height { get; set; }
}
However, when I am trying to deserialize the above response, I am getting the following error.
Error code is shown as "Not supported for deserialization of an array"
enter image description here
Can anyone help me with this?
Thank you!
Try using these classes created from json2csharp:
public class FaceRectangle
{
public int Top { get; set; }
public int Left { get; set; }
public int Width { get; set; }
public int Height { get; set; }
}
public class Emotion
{
public double Anger { get; set; }
public double Contempt { get; set; }
public double Disgust { get; set; }
public double Fear { get; set; }
public double Happiness { get; set; }
public double Neutral { get; set; }
public double Sadness { get; set; }
public double Surprise { get; set; }
}
public class FaceAttributes
{
public double Age { get; set; }
public Emotion Emotion { get; set; }
}
public class RootObject
{
public FaceRectangle FaceRectangle { get; set; }
public FaceAttributes FaceAttributes { get; set; }
}
Then you can deserialize your JSON Array response into List<RootObject using Newtonsoft.Json NuGet Package:
using Newtonsoft.Json;
...
var json = #"[{""faceRectangle"": {""top"": 214,""left"": 472,""width"": 450,""height"": 450},""faceAttributes"": {""age"": 19.0,""emotion"": {""anger"": 0.0,""contempt"": 0.0,""disgust"": 0.0,""fear"": 0.0,""happiness"": 0.0,""neutral"": 0.996,""sadness"": 0.003,""surprise"": 0.001}}}]";
var deserializedJson = JsonConvert.DeserializeObject<List<RootObject>>(json);

How to deserialize specific json string to ASP.NET MVC model?

I have json string like this:
{
"data": [
{
"id": 1,
"name": "Bitcoin",
"symbol": "BTC",
...
"quote": {
"USD": {
"price": 9283.92,
"volume_24h": 7155680000,
"percent_change_1h": -0.152774,
"percent_change_24h": 0.518894,
"market_cap": 158055024432,
"last_updated": "2018-08-09T22:53:32.000Z"
},
"BTC": {
"price": 1,
"volume_24h": 772012,
"percent_change_1h": 0,
"percent_change_24h": 0,
"percent_change_7d": 0,
"market_cap": 17024600,
"last_updated": "2018-08-09T22:53:32.000Z"
}
}
},
// objects like previous from which i need the data
],
"status": {
"timestamp": "2018-06-02T22:51:28.209Z",
...
}
}
How do I deserialize it into models like this:
public class MyModel
{
public string Name { get; set; }
public string Symbol { get; set; }
public string Price { get; set; }
public double Percent_change_1h { get; set; }
public double Percent_change_24h { get; set; }
public long Market_cap { get; set; }
public DateTime Last_updated { get; set; }
}
The field names in the model are the same as the key names in json string.
I'm new to C# and I couldn't find any helpful information about my question, especially because of this specific json string structure.
I'll be glad if you direct me any good links about this.
The model seems to be something like this.
public class Model
{
public List<Datum> data { get; set; }
public Status status { get; set; }
}
public class Status
{
public DateTime timestamp { get; set; }
}
public class Datum
{
public int id { get; set; }
public string name { get; set; }
public string symbol { get; set; }
public Quote quote { get; set; }
}
public class Quote
{
public USD USD { get; set; }
public BTC BTC { get; set; }
}
public class BTC
{
public int price { get; set; }
public int volume_24h { get; set; }
public int percent_change_1h { get; set; }
public int percent_change_24h { get; set; }
public int percent_change_7d { get; set; }
public int market_cap { get; set; }
public DateTime last_updated { get; set; }
}
public class USD
{
public double price { get; set; }
public object volume_24h { get; set; }
public double percent_change_1h { get; set; }
public double percent_change_24h { get; set; }
public object market_cap { get; set; }
public DateTime last_updated { get; set; }
}
You can also try creating model on (http://json2csharp.com/) by copying your valid json string.
Please let me know if this helps
Bottom line: You can (manually), but that's probably not what you're looking for.
Reason: Your model doesn't match the JSON structure, hence "manual"
You can use readily available tools in either Visual Studio or VS Code to help you with creating the proper model (e.g. Paste JSON As Code)
Once you get the "proper" model/s ready, go over JSON documentation for (de)serializing.
I had to fix some syntax errors on your json, so fixed version is following:
{
"data": [
{
"id": 1,
"name": "Bitcoin",
"symbol": "BTC",
"quote": {
"USD": {
"price": 9283.92,
"volume_24h": 7155680000,
"percent_change_1h": -0.152774,
"percent_change_24h": 0.518894,
"market_cap": 158055024432,
"last_updated": "2018-08-09T22:53:32.000Z"
},
"BTC": {
"price": 1,
"volume_24h": 772012,
"percent_change_1h": 0,
"percent_change_24h": 0,
"percent_change_7d": 0,
"market_cap": 17024600,
"last_updated": "2018-08-09T22:53:32.000Z"
}
}
}
],
"status": {
"timestamp": "2018-06-02T22:51:28.209Z"
}
}
Here is C# model classes matching with previous json:
public class Rootobject
{
public Datum[] data { get; set; }
public Status status { get; set; }
}
public class Status
{
public DateTime timestamp { get; set; }
}
public class Datum
{
public int id { get; set; }
public string name { get; set; }
public string symbol { get; set; }
public Quote quote { get; set; }
}
public class Quote
{
public USD USD { get; set; }
public BTC BTC { get; set; }
}
public class USD
{
public float price { get; set; }
public long volume_24h { get; set; }
public float percent_change_1h { get; set; }
public float percent_change_24h { get; set; }
public long market_cap { get; set; }
public DateTime last_updated { get; set; }
}
public class BTC
{
public int price { get; set; }
public int volume_24h { get; set; }
public int percent_change_1h { get; set; }
public int percent_change_24h { get; set; }
public int percent_change_7d { get; set; }
public int market_cap { get; set; }
public DateTime last_updated { get; set; }
}
Here is code snippet which you can use when deserializing your json. This snippet uses Json.NET-library.
var obj = JsonConvert.DeserializeObject<Rootobject>(File.ReadAllText("object.json"));

Part of JSON returned by API is serialised by JSON.NET but not all

I imagine this is more of a problem with my code rather than a problem with JSON.NET, but I'm not sure where I'm going wrong.
I have the following class below which is being used to serialise the json data found at this link: https://samples.openweathermap.org/data/2.5/weather?q=London,uk&appid=b6907d289e10d714a6e88b30761fae22
To construct this class I used a JSON to C# generator found on google.
Also below are the methods I use to pull and serialise the JSON data into a WeatherData object.
private string GetJsonFromWeb(string resource, string city)
{
var request = new RestRequest(resource, Method.GET);
request.AddParameter("q", city);
request.AddParameter("APPID", "af5e6fd579e0ddb303afc1774487c77b");
var fullUrl = client.BuildUri(request);
Console.WriteLine("Full URL: " + fullUrl.AbsoluteUri);
var response = client.Execute(request);
string json = response.Content;
return json;
}
private WeatherData SerializeJsonToWeatherData(string json)
{
WeatherData weatherData = JsonConvert.DeserializeObject<WeatherData>(json);
return weatherData;
}
These methods work successfully, as the JSON data can be used later in the application to display information within the GUI. However the MainData part of the JSON data is set to null after the JSON is pulled from the API.
class WeatherData
{
public Coord Coord { get; set; }
public List<Weather> Weather { get; set; }
public string Base { get; set; }
public MainData MainData { get; set; }
public int Visibility { get; set; }
public Wind Wind { get; set; }
public Clouds Clouds { get; set; }
public int Dt { get; set; }
public Sys Sys { get; set; }
public int Id { get; set; }
public string Name { get; set; }
public int Cod { get; set; }
}
public class Coord
{
public double Lon { get; set; }
public double Lat { get; set; }
}
public class Weather
{
public int Id { get; set; }
public string Main { get; set; }
public string Description { get; set; }
public string Icon { get; set; }
}
public class MainData
{
public double Temp { get; set; }
public int Pressure { get; set; }
public int Humidity { get; set; }
public double Temp_min { get; set; }
public double Temp_max { get; set; }
}
public class Wind
{
public double Speed { get; set; }
public int Deg { get; set; }
}
public class Clouds
{
public int All { get; set; }
}
public class Sys
{
public int Type { get; set; }
public int Id { get; set; }
public double Message { get; set; }
public string Country { get; set; }
public int Sunrise { get; set; }
public int Sunset { get; set; }
}
Sample JSON from above API
{
"coord": {
"lon": -0.13,
"lat": 51.51
},
"weather": [
{
"id": 300,
"main": "Drizzle",
"description": "light intensity drizzle",
"icon": "09d"
}
],
"base": "stations",
"main": {
"temp": 280.32,
"pressure": 1012,
"humidity": 81,
"temp_min": 279.15,
"temp_max": 281.15
},
"visibility": 10000,
"wind": {
"speed": 4.1,
"deg": 80
},
"clouds": {
"all": 90
},
"dt": 1485789600,
"sys": {
"type": 1,
"id": 5091,
"message": 0.0103,
"country": "GB",
"sunrise": 1485762037,
"sunset": 1485794875
},
"id": 2643743,
"name": "London",
"cod": 200
}
The JSON property is called main not mainData. JSON.Net can't find a property called mainData ans thus does not populate the MainData property of your POCOs

Categories

Resources