c# Deserializing nested Json - c#

This is the Json I am trying to parse/deserialize
{
"transactionId": "c34625a5-0590-48aa-8d1a-978df9aa9010",
"dal": {
"HourlyForecast": {
"geocode:40.77,-73.96:language:en-US:units:e": {
"data": {
"id": "40.77,-73.96",
"vt1hourlyForecast": [{
"processTime": "2017-07-12T12:00:00-0400",
"temperature": 85,
"precipPct": 15,
"precipType": "rain",
"uvIndex": 8,
"icon": 30,
"iconExtended": 3000,
"windDirCompass": "WSW",
"windDirDegrees": 253,
"windSpeed": 6,
"phrase": "Partly Cloudy",
"dayInd": "D",
"severity": 1,
"rh": 62,
"feelsLike": 92
}
//rest of json
I need to access vt1hourlyForecast[]
I've tried the dynamic JObject approach here
dynamic hourlydata = JObject.Parse(jsonData);
string hourlyForecast = hourlydata["Vt1hourlyForecast"].ToString();
Console.WriteLine(hourlydata);
But I get the error "Cannot perform runtime binding on a null reference"
I am really stuck on how to properly parse this. I have read a lot of similar questions but the nested Json is really confusing me any help will be greatly appreciated.

You need to navigate to the list property vt1hourlyForecast, since it's not a property of the outer object, but of a nested property e.g.
JObject jObject = JObject.Parse(json);
var dal = jObject["dal"];
var hourlyForecast = dal["HourlyForecast"];
var geocode = hourlyForecast["geocode:40.77,-73.96:language:en-US:units:e"];
var data = geocode["data"];
JArray forecast= (JArray)data["vt1hourlyForecast"];
foreach (JProperty forecastProperty in forecast)
{
Console.WriteLine(forecastProperty.Value);
}
In the example code I'm just casting the property to a JArray to show that that's possible, and it's enumerable.

Look at this answer:
You can do the following:
dynamic myNewObject = JsonConvert.DeserializeObject(json); which will
return a dynamic object which you can work with.
Console.WriteLine(myNewObject.data[0].description); Obviously, it will
fail if your JSON doesn't contain data array having objects with
description property.
The whole question/answer: https://stackoverflow.com/a/34284972/5056173
Based on this, you can use NewtonSoft Json to get the properties.
Another way is to filter it by yourself:
var startIndex = json.IndexOf("vt1hourlyForecast")-1;
var filteredJson1 = json.Substring(startIndex, json.Length - startIndex);
var endIndex = filteredJson1.IndexOf("}]")+2;
var filteredJson2 = filteredJson1.Substring(0, endIndex);
var jsonValidFilteredJson = "{"+filteredJson2+"}";
var yourObject = JsonConvert.DeserializeObject<Vt1hourlyForecast>(jsonValidFilteredJson);
You can use this class:
public class Vt1hourlyForecast
{
public string processTime { get; set; }
public int temperature { get; set; }
public int precipPct { get; set; }
public string precipType { get; set; }
public int uvIndex { get; set; }
public int icon { get; set; }
public int iconExtended { get; set; }
public string windDirCompass { get; set; }
public int windDirDegrees { get; set; }
public int windSpeed { get; set; }
public string phrase { get; set; }
public string dayInd { get; set; }
public int severity { get; set; }
public int rh { get; set; }
public int feelsLike { get; set; }
}

Related

How to get a specific field from json object by key:value?

I'm trying to save my data using json. I don't know how to get specific object group from a set of json objects.
[
{
"dateinformation": "2021-10-05:23:01",
"id": 1,
"MoveCount": 3,
"StartPoint": 2322,
"TotalDist": 2331,
"SafeDist": 21332,
"Feed": 2332,
"EndPoint":23245,
"Count":1221,
},
{
"dateinformation": "2021-10-05:26:01",
"id": 2,
"MoveCount": 3,
"StartPoint": 2322,
"TotalDist": 2331,
"SafeDist": 21332,
"Feed": 2332,
"EndPoint":23245,
"Count":1221,
},
{
"dateinformation": "2021-10-55:03:01",
"id": 3,
"MoveCount": 3,
"StartPoint": 2322,
"TotalDist": 2331,
"SafeDist": 21332,
"Feed": 2332,
"EndPoint":23245,
"Count":1221,
}]
is it possible to get/delete a specific object from a bundle of json object by its "id" value?
Do like that
NameSpace will include:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
Here you can replace your id by specificId
List<Root> myDeserializedClass = JsonConvert.DeserializeObject<List<Root>>(myJsonResponse); // myJsonResponse is My Source Json
int specificId = 123; // my dynamic
var specficObject = myDeserializedClass.Where(x => x.id == specificId);
Class for Deserialize your JSON response:
public class Root
{
public string dateinformation { get; set; }
public int id { get; set; }
public int MoveCount { get; set; }
public int StartPoint { get; set; }
public int TotalDist { get; set; }
public int SafeDist { get; set; }
public int Feed { get; set; }
public int EndPoint { get; set; }
public int Count { get; set; }
}
Also, I have noticed your JSON last column comma in last that should not be like that "Count" : 1221,

deserialize inconsistent json to object c#

Can someone tell me how to deserialize JSON to a C# (without using C# dynamic) object when JSON string is having dynamic array of data?
Given below JSON is having Boxes object and it can contain Array of fashion items (It can be pants, sweater, shoes,...etc)
{
"task": {
"id": 269740275,
"status": "success",
"error": null,
"date_created": "2017-02-16T10:33:41.827688Z",
"date_updated": "2017-02-16T10:33:42.417778Z",
"data": {
"width": 1062,
"boxes": {
"top-shirt": [
{
"xmin": 0.249980241060257,
"ymin": 0.1535395532846451,
"ymax": 0.476559966802597,
"xmax": 0.6146213412284851,
"proba": 0.9977585077285767
}
],
"shoe": [
{
"xmin": 0.3686676025390625,
"ymin": 0.9223044514656067,
"ymax": 0.9838011264801025,
"xmax": 0.4768480360507965,
"proba": 0.9748706817626953
}
],
"pants": [
{
"xmin": 0.3451904654502869,
"ymin": 0.4616038501262665,
"ymax": 0.909162700176239,
"xmax": 0.6047541499137878,
"proba": 0.9983627200126648
}
]
},
"height": 1503
}
}
}
You can use a dictionary to handle the dynamic part of the JSON (boxes).
Define your classes like this:
public class RootObject
{
public Task task { get; set; }
}
public class Task
{
public int id { get; set; }
public string status { get; set; }
public object error { get; set; }
public DateTime date_created { get; set; }
public DateTime date_updated { get; set; }
public Data data { get; set; }
}
public class Data
{
public int width { get; set; }
public Dictionary<string, List<Item>> boxes { get; set; }
public int height { get; set; }
}
public class Item
{
public double xmin { get; set; }
public double ymin { get; set; }
public double ymax { get; set; }
public double xmax { get; set; }
public double proba { get; set; }
}
Then deserialize like this:
RootObject obj = JsonConvert.DeserializeObject<RootObject>(json);
Fiddle: https://dotnetfiddle.net/Sxz8P3
Use NuGet to fetch the Newtonsoft.JSON package.
Then you can use linq-to-json to handle this kind of data object.
For example, assuming your example JSON string is stored in input,
var message = JObject.Parse(input);
var width = (int)message["task"]["data"]["width"];
var height = (int)message["task"]["data"]["height"];
Console.WriteLine(width + " " + height);
var boxes = message["task"]["data"]["boxes"];
foreach (var box in boxes.Children<JProperty>())
{
Console.WriteLine(box.Name) ;
}
This is pretty close to Javascript and works well.
I think O. Jones provided the easiest solution, using Newtonsoft, Newtonsoft is literally the best possible way to do anything with JSON in C# and without any headaches.
Here's one of the simplest examples
string json_string = #"{
Firstname: ""Jane"",
Lastname: ""Doe"",
Age: 36,
IsEmployed: true,
IsMarried: true,
Children: 4
}";
var person = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(json_string);
Console.WriteLine(person.Forename);
Console.WriteLine(person.Lastname);
Console.WriteLine(person.Age);
Console.WriteLine(person.IsEmployed);
Console.WriteLine(person.IsMarried);
Console.WriteLine(person.Children);
It generates objects on the fly, no matter the structure!
I wrote a simple, easy-to-follow article here https://turmanauli.medium.com/a-complete-guide-for-serializing-json-to-dynamic-objects-on-the-fly-in-c-7ab4799f648d
about how to use Newtonsoft in your Visual Studio project.

Read Json data from text file C#

I have a text file with below format data
[
{
"SponsorID": 1,
"FirstBAID": 7395836
},
{
"SponsorID": 2,
"FirstBAID": 3509279,
"SecondBAID": 2947210
},
{
"SponsorID": 3,
"FirstBAID": 1776294,
"SecondBAID": 6503843
},
{
"SponsorID": 4,
"FirstBAID": 8014528,
"SecondBAID": 6203155
},
{
"SponsorID": 5,
"FirstBAID": 5968769,
"SecondBAID": 7410195,
"ThirdBAID":8950170,
}
]
I want to read this data as a List & then i need to query by SponsorID.
I have created a class like this
public class SponsorInfo
{
public decimal SponsorID { get; set; }
public decimal FirstBAID { get; set; }
public decimal SecondBAID { get; set; }
public decimal ThirdBAID { get; set; }
}
Now how can i read text file data & bind SponsorInfo class ?
Install Newtonsoft.Json nuget package from NuGet package manager console:
PM> Install-Package Newtonsoft.Json
Then:
var jsonText = File.ReadAllText("filepath");
var sponsors = JsonConvert.DeserializeObject<IList<SponsorInfo>>(jsonText);
To query on SponsorID you can use LINQ:
var sponsor5 = sponsors.FirstOrDefault(x => x.SponsorID == 5);
If you often need a lookup by SponsorID, you could convert the result to a dictionary where the key is the SponsorID. This will improve performance as it doesn't need to enumerate through the entire list for each lookup. I also suggest you change the type of SponsorID to an int instead of a decimal.
var sponsorsById = sponsors.ToDictionary(x => x.SponsorID);
Then you can easily access it like:
if (sponsorsById.ContainsKey(5))
var sponsor5 = sponsorsById[5];
You need to install Newtonsoft.Json and then you need use it:
using Newtonsoft.Json;
class Program
{
public void LoadJson()
{
using (StreamReader r = new StreamReader("file.json"))
{
string json = r.ReadToEnd();
List<SponsorInfo> items = JsonConvert.DeserializeObject<List<SponsorInfo>>(json);
}
}
public class SponsorInfo
{
public decimal SponsorID { get; set; }
public decimal FirstBAID { get; set; }
public decimal SecondBAID { get; set; }
public decimal ThirdBAID { get; set; }
}
static void Main(string[] args)
{
dynamic array = JsonConvert.DeserializeObject(json);
foreach (var item in array)
{
Console.WriteLine("{0} {1}", item.temp, item.vcc);
}
}
}
Extend the class by creating a list object
public class SponsorInfo
{
public decimal SponsorID { get; set; }
public decimal FirstBAID { get; set; }
public decimal SecondBAID { get; set; }
public decimal ThirdBAID { get; set; }
}
public class SponsorInfoList
{
public Dictionary<string, SponsorInfo> SIList { set; get; }
}
Deserialize the file as,
var obj = JsonConvert.DeserializeObject<SIList >(File.ReadAllText(FileName));
Then you can read it,
foreach(var listItem in res.SIList )
{
Console.WriteLine("SponsorID ={0}, FirstBAID ={1}, SecondBAID ={2}, ThirdBAID ={3}", listItem.SponsorID, listItem.FirstBAID, listItem.SecondBAID, listItem.ThirdBAID );
}
There may be syntactical errors but the approach remains same.
Feel free to leave a message!
You need to deserialize into your object like:
Sponsor spon = JsonConvert.DeserializeObject<Sponsor>(json);

cant figure out how to map this json into C# classes

So I have the json below that I want to Deseralize into Classes so I can work with it. But the issues is that the top two fields are a different type to all the rest
"items": {
"averageItemLevel": 718,
"averageItemLevelEquipped": 716,
"head": { ... },
"chest": { ... },
"feet": { ... },
"hands": { ... }
}
Where ... is a the Item class below, but the problem is that 2 of the fields are ints and the rest are Item, there are about 20 fields in total. So what I'd like to do is put them into a Dictionary<string, Item> but the 2 int fields are preventing me from Deseralizing it into that. I'm using JavaScriptSerializer.Deserialize<T>() to do this.
I could have each item as it's own class with the name of the item as the name of the class, but I find that to be very bad, repeating so much each time, also very hard to work with later since I cant iterate over the fields, where as I could a Dictionary. Any idea how I could overcome this?
public class Item
{
public ItemDetails itemDetails { get; set; }
public int id { get; set; }
public string name { get; set; }
public string icon { get; set; }
public int quality { get; set; }
public int itemLevel { get; set; }
public TooltipParams tooltipParams { get; set; }
public List<Stat> stats { get; set; }
public int armor { get; set; }
public string context { get; set; }
public List<int> bonusLists { get; set; }
}
Update: from the comments I came up with this solution
JObject jsonObject = JObject.Parse(json);
jsonObject["averageItemLevel"] = int.Parse(jsonObject["items"]["averageItemLevel"].ToString());
jsonObject["averageItemLevelEquipped"] = int.Parse(jsonObject["items"]["averageItemLevelEquipped"].ToString());
jsonObject["items"]["averageItemLevel"].Parent.Remove();
jsonObject["items"]["averageItemLevelEquipped"].Parent.Remove();
var finalJson = jsonObject.ToString(Newtonsoft.Json.Formatting.None);
var character = _serializer.Deserialize<Character>(finalJson);
character.progression.raids.RemoveAll(x => x.name != "My House");
return character
If I add these two classes to match your JSON I can serialize and deserialize the objects:
public class root
{
public Items items { get; set; }
}
public class Items
{
public int averageItemLevel { get; set; }
public int averageItemLevelEquipped { get; set; }
public Item head {get;set;}
public Item chest {get;set;}
public Item feet {get;set;}
public Item hands {get;set;}
}
Test rig with the WCF Serializer:
var obj = new root();
obj.items = new Items
{
averageItemLevel = 42,
feet = new Item { armor = 4242 },
chest = new Item { name = "super chest" }
};
var ser = new DataContractJsonSerializer(typeof(root));
using (var ms = new MemoryStream())
{
ser.WriteObject(ms, obj);
Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
Console.WriteLine("and deserialize");
ms.Position = 0;
var deserializeObject = (root) ser.ReadObject(ms);
Console.WriteLine(deserializeObject.items.feet.armor);
}
And with the JavaScriptSerializer:
var jsser = new JavaScriptSerializer();
var json = jsser.Serialize(obj);
Console.WriteLine(json);
Console.WriteLine("and deserialize");
var djson = jsser.Deserialize<root>(json);
Console.WriteLine(djson.items.feet.armor);
Both serializers give the same result for your given JSON.

Can't deserialize json

Can someone help me figure out how to deserialize this using json.net in C#? I have already successfully parsed a different json but its format was different. I've tried to use object and it says it needs to be an array and then I change it to array it says it needs to be an array..
Oh and there can be additional arrays with different "TYPE"..
"[
{
"ID": 1,
"TYPE": 1,
"APP_TAG": 1,
"alert": "[13:13] This is a Test Message - 0.",
"sound": "Default",
"badge": 0
}
]"
Since it is an array/list
public class Item
{
public int ID { get; set; }
public int TYPE { get; set; }
public int APP_TAG { get; set; }
public string alert { get; set; }
public string sound { get; set; }
public int badge { get; set; }
}
var items = JsonConvert.DeserializeObject<List<Item>>(json);
string json = #"[
{
'ID': 1,
'TYPE': 1,
'APP_TAG': 1,
'alert': '[13:13] This is a Test Message - 0.',
'sound': 'Default',
'badge': 0
}
]";
var items = Newtonsoft.Json.JsonConvert.DeserializeObject(json);

Categories

Resources