C# Newton deserialize JSON with sub lists - c#

Let's say that this is the API jsonresponse from Facebook (at the end).
Until now i am deserializing the newton jsongetting the id and created_time for each one, but the second one includes reactions which is a list and a comments element which is another list.
I am using the following to loop through posts:
var posts = JsonConvert.DeserializeObject<FacebookPostData>(fbData);
And the
for each post in posts....
id = post.id
How inside the loop that i am could loop to the post Reactions and post Comments.
The class that i have so far and working is:
public class FacebookPostData
{
public List<FacebookPost> Data { get; set; }
}
public class FacebookPost
{
public string id { get; set; }
public string created_time { get; set; }
}
The API response is:
{
"data": [{
"id": "",
"created_time": ""
},
{
"id": "",
"created_time": "",
"reactions": {
"data": [{
"id": "",
"name": "",
"type": ""
},
{
"id": "",
"name": "",
"type": ""
}
],
"paging": {
"cursors": {
"before": "",
"after": ""
}
}
},
"comments": {
"data": [{
"created_time": "",
"from": {
"name": "",
"id": ""
},
"message": "",
"id": ""
}],
"paging": {
"cursors": {
"before": "",
"after": ""
}
}
}
}
],
"paging": {
"previous": "",
"next": ""
}
}
Thank you!

Your classes could be structured in this way:
public class FacebookPostData
{
public List<FacebookPost> data { get; set; }
public Paging3 paging { get; set; }
public FacebookPostData()
{
this.data = new List<FacebookPost>();
this.paging = new Paging3();
}
}
public class FacebookPost
{
public string id { get; set; }
public string created_time { get; set; }
public Reactions reactions { get; set; }
public Comments comments { get; set; }
public FacebookPost()
{
this.reactions = new Reactions();
this.comments = new Comments();
}
}
public class Paging3
{
public string previous { get; set; }
public string next { get; set; }
}
public class Reactions
{
public List<Data2> data { get; set; }
public Paging paging { get; set; }
public Reactions()
{
this.data = new List<Data2>();
this.paging = new Paging();
}
}
public class Data2
{
public string id { get; set; }
public string name { get; set; }
public string type { get; set; }
}
public class Paging
{
public Cursors cursors { get; set; }
public Paging()
{
this.cursors = new Cursors();
}
}
public class Cursors
{
public string before { get; set; }
public string after { get; set; }
}
public class Comments
{
public List<Data3> data { get; set; }
public Paging2 paging { get; set; }
public Comments()
{
this.data = new List<Data3>();
this.paging = new Paging2();
}
}
public class Data3
{
public string created_time { get; set; }
public From from { get; set; }
public string message { get; set; }
public string id { get; set; }
public Data3()
{
this.from = new From();
}
}
public class Paging2
{
public Cursors2 cursors { get; set; }
public Paging2()
{
this.cursors = new Cursors2();
}
}
public class From
{
public string name { get; set; }
public string id { get; set; }
}
public class Cursors2
{
public string before { get; set; }
public string after { get; set; }
}
So, you can do something like this:
var posts = JsonConvert.DeserializeObject<FacebookPostData>(fbData);
foreach(var post in posts.data)
{
Console.WriteLine(post.id);
// Reactions...
foreach(var reaction in post.reactions.data)
{
Console.WriteLine(reaction.id);
}
// Comments...
foreach(var comment in post.comments.data)
{
Console.WriteLine(comment.id);
Console.WriteLine(comment.from.id);
Console.WriteLine(comment.from.name);
}
}
See this demo.
Hope this helps.

Related

How can I read all the values from this array of arrays in JSON?

Community,
I want to read all the values from this json. I am using C#. How do I manage do that? I am trying to use the openroute service distance matrix.
My Idea:
string responseData = await response.Content.ReadAsStringAsync();
var jobject = JObject.Parse(responseData);
var onlydistance = jobject.SelectTokens("$.distances[*]")
.Values<double>()
.ToArray();
My JSON:
{
"distances": [[0, 108628.26, 2669713, 11595025], [108952.97, 0, 2674477.75, 11609762], [2688555, 2681139.5, 0, 8405009], [11596626, 11611808, 8734262, 0]],
"destinations": [
{
"location": [9.700817, 48.476406],
"snapped_distance": 118.92
},
{
"location": [9.207773, 49.153882],
"snapped_distance": 10.54
},
{
"location": [37.572963, 55.801279],
"snapped_distance": 17.45
},
{
"location": [115.665017, 38.100717],
"snapped_distance": 648.79
}
],
"sources": [
{
"location": [9.700817, 48.476406],
"snapped_distance": 118.92
},
{
"location": [9.207773, 49.153882],
"snapped_distance": 10.54
},
{
"location": [37.572963, 55.801279],
"snapped_distance": 17.45
},
{
"location": [115.665017, 38.100717],
"snapped_distance": 648.79
}
],
"metadata":
{
"attribution": "openrouteservice.org | OpenStreetMap contributors",
"service": "matrix",
"timestamp": 1603348601609,
"query":
{
"locations": [[9.70093, 48.477473], [9.207916, 49.153868], [37.573242, 55.801281], [115.663757, 38.106467]],
"profile": "cycling-road",
"responseType": "json",
"metricsStrings": ["DISTANCE"],
"metrics": ["distance"],
"units": "m"
},
"engine":
{
"version": "6.3.0",
"build_date": "2020-10-19T02:01:48Z",
"graph_date": "2020-10-12T06:58:07Z"
}
}
}
Use a generator/converter to generate Json Classes eg: https://json2csharp.com/
Sample code:
public Form1()
{
InitializeComponent();
string jsonData = File.ReadAllText(#"c:\root\t01.json");
Root root = JsonConvert.DeserializeObject<Root>(jsonData);
}
public class Root {
public List<List<double>> distances { get; set; }
public List<Destination> destinations { get; set; }
public List<Source> sources { get; set; }
public Metadata metadata { get; set; }
}
public class Destination {
public List<double> location { get; set; }
public double snapped_distance { get; set; }
}
public class Source {
public List<double> location { get; set; }
public double snapped_distance { get; set; }
}
public class Query {
public List<List<double>> locations { get; set; }
public string profile { get; set; }
public string responseType { get; set; }
public List<string> metricsStrings { get; set; }
public List<string> metrics { get; set; }
public string units { get; set; }
}
public class Engine {
public string version { get; set; }
public DateTime build_date { get; set; }
public DateTime graph_date { get; set; }
}
public class Metadata {
public string attribution { get; set; }
public string service { get; set; }
public long timestamp { get; set; }
public Query query { get; set; }
public Engine engine { get; set; }
}

Trouble parsing this json

Okay, so I have this response model below and I'm trying to retrieve a List of Daily. Below the response model and the receiving json. I added an additional snippet of code where I retrieve a list of agent objects, but I have not been able to retrieve a Daily List from the list of agent objects. I'm not sure what I'm doing wrong here and could really use some help. Thank you.
{
"accountId": "",
"policiesInForce": [
{
"daily": [
{
"date": "Date",
"pifCount": "",
"noPopPifCount": "",
"popPifCount": "",
"cleanPopPifCount": ""
}
]
}
],
"pathsToPartnership": [
{
"pathsToPartnershipInd": "bool",
"pathsToPartnershipLevel": ""
}
],
"overrides": [
{
"startDate": "date",
"endDate": "date",
"overrideTier": "",
"turnOffPlatinumFlag": "bool"
}
],
"agents": [
{
"agentCode": "",
"pathsToPartnership": [
{
"pathsToPartnershipInd": "bool",
"pathsToPartnershipLevel": ""
}
],
"policiesInForce": [
{
"daily": [
{
"date": "Date",
"pifCount": "",
"noPopPifCount": "",
"popPifCount": "",
"cleanPopPifCount": ""
}
]
}
],
"exceptions": [
{
"platinumInd": "bool",
"newAgentTenureDate": "date",
"maAgentTenureDate": "date",
"residentStCd": "",
"clPremiumAmt": ""
}
],
"overrides": [
{
"startDate": "date",
"endDate": "date",
"overrideTier": "",
"turnOffPlatinumFlag": "bool"
}
],
"commissionLevel": [
{
"pifLevel": "",
"effectiveDate": "Date",
"endDate": "Date"
}
]
}
]
}
public class PoliciesInForce
{
public List<Daily> Daily { get; set; }
}
public class Daily
{
public string Date { get; set; }
public int PifCnt { get; set; }
public int NoPopPifCnt { get; set; }
public int PopPifCnt { get; set; }
public int CleanPopPifCount { get; set; }
}
public class PoliciesInForce2
{
public List<Daily> Daily { get; set; }
}
public class CommissionLevels
{
public List<object> CommissionLevel { get; set; }
}
public class Exceptions
{
public string ExceptionId { get; set; }
public string PlatinumInd { get; set; }
public string NewAgentTenureDate { get; set; }
public string MAAgentTenureDate { get; set; }
public string ResidentStCd { get; set; }
public object CLPremiumAmt { get; set; }
}
public class PathToPartnership
{
public string LevelCode { get; set; }
public string LevelName { get; set; }
public string StartDate { get; set; }
public object EndDate { get; set; }
}
public class Agent
{
public string AgentCode { get; set; }
public PoliciesInForce2 PoliciesInForce { get; set; }
public CommissionLevels CommissionLevels { get; set; }
public Exceptions Exceptions { get; set; }
public PathToPartnership PathToPartnership { get; set; }
}
public class PathToPartnership2
{
public string LevelCode { get; set; }
public string LevelName { get; set; }
public string StartDate { get; set; }
public string EndDate { get; set; }
}
public class Account
{
public int AccountId { get; set; }
public string CommissionLevel { get; set; }
public PoliciesInForce PoliciesInForce { get; set; }
public List<Agent> Agents { get; set; }
public PathToPartnership2 PathToPartnership { get; set; }
}
public class RootObject
{
public Account Account { get; set; }
}
}
var agents = new List<Agent>();
string response = message.Content.ReadAsStringAsync().Result;
var account = JsonConvert.DeserializeObject<RootObject>(response);
var list = new List<Daily>();
foreach (Agent agent in account.Account.Agents)
{
agents.Add(agent);
}
for (int i = 0; i < agents.Count; i++)
{
list[i].Date = agents[i].PoliciesInForce.Daily[i].Date;
list[i].PifCnt = agents[i].PoliciesInForce.Daily[i].PifCnt;
list[i].NoPopPifCnt = agents[i].PoliciesInForce.Daily[i].NoPopPifCnt;
list[i].PopPifCnt = agents[i].PoliciesInForce.Daily[i].PopPifCnt;
list[i].CleanPopPifCount = agents[i].PoliciesInForce.Daily[i].CleanPopPifCount;
}
This creates an empty list.
var list = new List<Daily>();
Then you're trying to assign to an index in the list, when there are no items in the list.
for (int i = 0; i < agents.Count; i++)
{
list[i].Date = agents[i].PoliciesInForce.Daily[i].Date;
list[i].PifCnt = agents[i].PoliciesInForce.Daily[i].PifCnt;
list[i].NoPopPifCnt = agents[i].PoliciesInForce.Daily[i].NoPopPifCnt;
list[i].PopPifCnt = agents[i].PoliciesInForce.Daily[i].PopPifCnt;
list[i].CleanPopPifCount = agents[i].PoliciesInForce.Daily[i].CleanPopPifCount;
}
That is, when you say list[i], it assumes that list[i] has an instance of Daily.
What you need to do is Add().
for (int i = 0; i < agents.Count; i++)
{
list.Add(new Daily
{
Date = agents[i].PoliciesInForce.Daily[i].Date,
PifCnt = agents[i].PoliciesInForce.Daily[i].PifCnt,
NoPopPifCnt = agents[i].PoliciesInForce.Daily[i].NoPopPifCnt,
PopPifCnt = agents[i].PoliciesInForce.Daily[i].PopPifCnt,
CleanPopPifCount = agents[i].PoliciesInForce.Daily[i].CleanPopPifCount
});
}

c# Serialize multiple nested objects to json

I have a need to serialize this from Objects, or possibly a object of objects in c#. I have tried multiple different ways to get the same output and have failed. Here is the JSON
{
"resourceType": "Observation",
"code": {
"coding": [
{
"system": "http://",
"code": "3637",
"display": "Gene"
}
],
"text": "Dip"
},
"subject": {
"reference": "Pat",
"display": ""
},
"valueString": "*1/*1",
"component": [
{
"code": {
"coding": [
{
"system": "http://",
"code": "",
"display": "Gene"
}
]
},
"valueCodeableConcept": {
"coding": [
{
"system": "http://",
"code": "",
"display": "CYP"
}
]
}
}
]
}
i created the following objects from this. I tried to make a object containing them and then use Newtonsoft to serialize it but I can not get it right
here are the objects
public class Rootobject
{
public string resourceType { get; set; }
public Code code { get; set; }
public Subject subject { get; set; }
public string valueString { get; set; }
public Component[] component { get; set; }
}
public class Code
{
public Coding[] coding { get; set; }
public string text { get; set; }
}
public class Coding
{
public string system { get; set; }
public string code { get; set; }
public string display { get; set; }
}
public class Subject
{
public string reference { get; set; }
public string display { get; set; }
}
public class Component
{
public Code1 code { get; set; }
public Valuecodeableconcept valueCodeableConcept { get; set; }
}
public class Code1
{
public Coding1[] coding { get; set; }
}
public class Coding1
{
public string system { get; set; }
public string code { get; set; }
public string display { get; set; }
}
public class Valuecodeableconcept
{
public Coding2[] coding { get; set; }
}
public class Coding2
{
public string system { get; set; }
public string code { get; set; }
public string display { get; set; }
}
As Sir Rufo pointed out(for completeness of answer)
using System;
using Newtonsoft.Json;
public class Program
{
public static void Main()
{
var obj = CreateRootObject();
var str = JsonConvert.SerializeObject( obj, Formatting.Indented );
Console.WriteLine(str);
}
private static Rootobject CreateRootObject()
{
var obj = new Rootobject() {
resourceType = "Observation",
code = new Code() {
coding = new Coding[] {
new Coding() {
system = "http://",
code = "3637",
display = "Gene",
},
},
text = "Dip",
},
subject = new Subject() {
reference = "Pat",
display = "",
},
valueString = "*1/*1",
component = new Component[] {
new Component() {
code = new Code2(){
coding = new Coding[] {
new Coding(){
system = "http://",
code = "3637",
display = "Gene",
},
},
},
valueCodeableConcept = new Valuecodeableconcept(){
coding = new Coding[] {
new Coding(){
system = "http://",
code = "",
display = "CYP",
},
},
},
},
},
};
return obj;
}
}
public class Rootobject
{
public string resourceType { get; set; }
public Code code { get; set; }
public Subject subject { get; set; }
public string valueString { get; set; }
public Component[] component { get; set; }
}
public class Code
{
public Coding[] coding { get; set; }
public string text { get; set; }
}
public class Coding
{
public string system { get; set; }
public string code { get; set; }
public string display { get; set; }
}
public class Subject
{
public string reference { get; set; }
public string display { get; set; }
}
public class Component
{
public Code2 code { get; set; }
public Valuecodeableconcept valueCodeableConcept { get; set; }
}
public class Code2
{
public Coding[] coding { get; set; }
}
public class Valuecodeableconcept
{
public Coding[] coding { get; set; }
}

Accessing deeply nested JSON objects in c# using NewtonSoft Deserialization

I am having a very difficult time reaching some deeply nested objects in my JSON
I have a directory with roughly 500 JSON files that I need to read through, and output certain data from so I load the files like this:
public static void getJsonFiles()
{
int i = 0;
string directory = #"Z:\My_JSON_FILES\DataFilesForAnalysis\DataFilesAsJSON";
string[] jsonPath = Directory.GetFiles(directory, "*.json");
foreach(string item in jsonPath)
{
jsonReader(item, i);
i++;
}
}
Once I have the file loaded, I am reading it through File.ReadAllText so I am doing this:
public static void jsonReader(string item, int i)
{
string readJson = File.ReadAllText(item);
RootObject rootObj = JsonConvert.DeserializeObject<RootObject>(readJson);
var resReport = rootObj.ResultsReport;
...
I have created objects of all of the JSON using json2csharp, but when I try to access the deeply nested objects using dot notation (rootObj.ResultsReport.FinalReport.VariantProperties.VariantProperty.VariantName), I get an error 'Object does not contain a definition for FinalReport and no extension method FinalReport...'
My object definition looks like this:
public class VariantProperty
{
public string geneName { get; set; }
public string isVUS { get; set; }
public string variantName { get; set; }
}
public class VariantProperties
{
public string[] VariantProperty { get; set; }
}
public class FinalReport
{
public Object Application { get; set; }
public string ReportId { get; set; }
public string SampleName { get; set; }
public string Version { get; set; }
public Object Sample { get; set; }
public string PertinentNegatives { get; set; }
public Object Summaries { get; set; }
public Object VariantProperties { get; set; }
public Object Genes { get; set; }
public Object Trials { get; set; }
public Object References { get; set; }
public Object Signatures { get; set; }
public Object AAC { get; set; }
}
public class ResultsReport
{
public Object FinalReport { get; set; }
public Object VariantReport { get; set; }
}
public class RootObject
{
public Object ResultsReport { get; set; }
}
The JSON looks like this:
"ResultsReport": {
"CustomerInformation": null,
"FinalReport": {
"#xmlns:xsd": "http://www.w3.org/2001/XMLSchema",
"#StagingId": "XXXXXXXX",
"#clinicalId": "XXXXXXXX",
"Application": {
"ApplicationSettings": {
"ApplicationSetting": {
"Name": "Statement",
"Value": "XXXXXXXX"
}
}
},
"ReportId": "XXXXXXXX",
"SampleName": "XXXXXXXX",
"Version": "1",
"Sample": {
"FM_Id": "XXXXXXXX",
"SampleId": "XXXXXXXX",
"BlockId": "XXXXXXXX",
"TRFNumber": "XXXXXXXX",
"TestType": "XXXXXXXX",
"SpecFormat": "XXXXXXXX",
"ReceivedDate": "XXXXXXXX"
},
"PertinentNegatives": null,
"Summaries": {
"#alterationCount": "XXXXXXXX",
"#clinicalTrialCount": "XXXXXXXX",
"#resistiveCount": "XXXXXXXX",
"#sensitizingCount": "XXXXXXXX"
},
"VariantProperties": {
"VariantProperty": [
{
"#geneName": "BARD1",
"#isVUS": "true",
"#variantName": "P358_S364del"
},
{
"#geneName": "GATA2",
"#isVUS": "true",
"#variantName": "P161A"
},
{
"#geneName": "LRP1B",
"#isVUS": "true",
"#variantName": "V4109I"
},
{
"#geneName": "MLL2",
"#isVUS": "true",
"#variantName": "P1191L"
},
{
"#geneName": "NTRK1",
"#isVUS": "true",
"#variantName": "G18E"
},
{
"#geneName": "NUP98",
"#isVUS": "true",
"#variantName": "A447T"
},
{
"#geneName": "TET2",
"#isVUS": "true",
"#variantName": "D1121Y"
},
{
"#geneName": "WT1",
"#isVUS": "true",
"#variantName": "T377_G397>S"
}
]
}
What am I doing wrong? I've followed so many different examples but it just wont seem to work
Write properties like
public ResultsReport ResultsReport { get; set; }
public FinalReport FinalReport { get; set; }
You are using object as property type, thats wrong, it is not about JSON deserialization.
As Volkan said the issue isn't the JSON deserialization. I got your json working by structuring my classes like so:
public class VariantProperty
{
public string geneName { get; set; }
public string isVUS { get; set; }
public string variantName { get; set; }
}
public class VariantProperties
{
public List<VariantProperty> VariantProperty { get; set; }
}
public class FinalReport
{
public Object Application { get; set; }
public string ReportId { get; set; }
public string SampleName { get; set; }
public string Version { get; set; }
public Object Sample { get; set; }
public string PertinentNegatives { get; set; }
public Object Summaries { get; set; }
public VariantProperties VariantProperties { get; set; }
public Object Genes { get; set; }
public Object Trials { get; set; }
public Object References { get; set; }
public Object Signatures { get; set; }
public Object AAC { get; set; }
}
public class ResultsReport
{
public FinalReport FinalReport { get; set; }
}
public class RootObject
{
public ResultsReport ResultsReport { get; set; }
}

How to deserialize json with class name as dynamic values

How can I De-serialize following json?
{
"data": {
"11396": {
"description": "Timer project",
"status": "ACTIVE",
"customer": {
"locations": {},
"id": 96626
},
"tasks": [
{
"description": "Timer Task",
"unit": "h",
"vatPct": 0.2,
"unitPrice": 12,
"billable": true,
"id": 19660
}
],
"price": 0,
"pricing": "UNIT",
"allowProducts": true,
"hasUninvoicedItems": false,
"id": 11396
},
"11397": {
"description": "Timer Project 2",
"status": "ACTIVE",
"customer": {
"locations": {},
"id": 96626
},
"tasks": [
{
"description": "Timer Task2",
"unit": "h",
"vatPct": 0.05,
"unitPrice": 20,
"billable": true,
"id": 19655
}
],
"price": 0,
"pricing": "UNIT",
"allowProducts": true,
"hasUninvoicedItems": false,
"id": 11397
}
},
"ok": true
}
The problem is that values 11396, 11397 as class name (if convert to c#) which are actually ids of that particular record. so when converting this json to c# using http://json2csharp.com. it shows as this
public class Locations
{
}
public class Customer
{
public Locations locations { get; set; }
public int id { get; set; }
}
public class Task
{
public string description { get; set; }
public string unit { get; set; }
public double vatPct { get; set; }
public double unitPrice { get; set; }
public bool billable { get; set; }
public int id { get; set; }
}
public class __invalid_type__11397
{
public string description { get; set; }
public string status { get; set; }
public Customer customer { get; set; }
public List<Task> tasks { get; set; }
public double price { get; set; }
public string pricing { get; set; }
public bool allowProducts { get; set; }
public bool hasUninvoicedItems { get; set; }
public int id { get; set; }
}
public class Locations2
{
}
public class Customer2
{
public Locations2 locations { get; set; }
public int id { get; set; }
}
public class Task2
{
public string description { get; set; }
public string unit { get; set; }
public double vatPct { get; set; }
public double unitPrice { get; set; }
public bool billable { get; set; }
public int id { get; set; }
}
public class __invalid_type__11396
{
public string description { get; set; }
public string status { get; set; }
public Customer2 customer { get; set; }
public List<Task2> tasks { get; set; }
public double price { get; set; }
public string pricing { get; set; }
public bool allowProducts { get; set; }
public bool hasUninvoicedItems { get; set; }
public int id { get; set; }
}
public class Data
{
public __invalid_type__11397 __invalid_name__11397 { get; set; }
public __invalid_type__11396 __invalid_name__11396 { get; set; }
}
public class RootObject
{
public Data data { get; set; }
public bool ok { get; set; }
}
any help is much appreciated.
I resolved this issue by parsing the json string to JTOKEN and the querying the required data.
This was possible because my datas inside json was static
JToken token = JObject.Parse(response);
var justDaily = token["data"];
ProjectList = new List<Project>();
foreach (JToken child in justDaily.Children())
{
foreach (JToken grandChild in child)
{
Project temp = JsonConvert.DeserializeObject<Project>(grandChild.ToString().Replace("\r\n", ""));
ProjectList.Add(temp);
}
}
Hope this will help someone else also

Categories