How to deserialize Json to dictionary in c# - c#

I have a json array as ahown below with two keys "entities" and "TotalResults". within entities there is "Fields". I want to obtain the elements within "Fields" i.e, "name" and "values". so that i can iterate over the Fields to find the matching name and it's respective value. I have tried most of the solutions out there, nothing seems to give the result i want. Any help would be admired.
below is the Json array :
{"entities": [
{
"Fields": [
{
"Name": "test-id",
"values": [
{
"value": "268"
}
]
},
{
"Name": "os-config",
"values": [
{}
]
},
{
"Name": "pc-mobile-host",
"values": [
{}
]
}
}
],
"TotalResults": 2}
Code i tried are below (only two are mentioned though i tried lots of other methods) :
1.
Dictionary<string,object> Result= JsonConvert.DeserializeObject<Dictionary<string,object>>(json);
2.
public class Fields
{
[JsonProperty("values")]
public IList<object> values { get; set; }
[JsonProperty("Name")]
public string Name { get; set; }
}
public class RootObject
{
public IList<Fields> Fields { get; set; }
}
var Result = JsonConvert.DeserializeObject<RootObject>(json);

First (using Newtonsoft.Json) parse json to JObject and then you can access and iterate Fields objects using SelectToken.
There was still error in your JSON while writing this answer so I've modified it to be valid
var json = #"{""entities"":[{""Fields"":[{""Name"":""test-id"",""values"":[{""value"":""268""}]},{""Name"":""os-config"",""values"":[{}]},{""Name"":""pc-mobile-host"",""values"":[{}]}]}],""TotalResults"":2}";
var jObject = JObject.Parse(json);
var fields = jObject.SelectToken("$..Fields").ToList();
foreach (var field in fields)
{
}

Related

Cross-referencing two parts of one JSON file in C#?

Newbie question. I have a semi-complex JSON file that I have parsed in my program. The relevant parts are below:
{
"version": "36",
"released": "20220223",
"samples": {
"Samp1": [
{
"code": "A01",
"status": "Optimal",
"bestBy": "20210918",
"expires": "20211018",
"elementKeys": {
"H": [
"Hydrogen-std1-slt4"
]
}
},
{
"code": "A02",
"status": "Optimal",
"bestBy": "20211201",
"expires": "20220501",
"elementKeys": {
"H": [
"Hydrogen-std1-slt5"
]
}
},
{
"code": "A03",
"status": "Optimal",
"bestBy": "20230201",
"expires": "20230801",
"elementKeys": {
"H": [
"Hydrogen-std1-slt6"
]
}
}
],
"Samp2": [ ...
"Samp3": [ ...
"Samp4": [ ...
},
"element": {
"Hydrogen-std1-slt4": {
"format": "1.0",
"position": 4,
"standard": "std1",
...
...
}
What I need to do is populate some windows form controls with data from this file. However, thanks to the odd architecture, I'm a little frustrated over how to populate the controls for "code", "status", "bestBy", etc contained within the "samples" arrays (Samp1, 2, 3, and 4).
Only some of the samples are relevant and the relevancy is defined by whether or not the name of the element key is found further below in the JSON file. So, using the example above, within "element", the object "Hydrogen-std1-slt4" is found in the body of the JSON file with its own key-value pairs. I would like the program to see that and recognize that "Hydrogen-std1-slt4" is also found within the object in the "Samp1" array with the code "A01", the status of "Optimal", the best-by date of "20210918", and that it expires on "20211018". Since it isn't found in any other place in "Samp1", the program can ignore the other objects.
What would be the easiest, most logical way to go about making a conditional for that?
try this code
var jsonParsed = JObject.Parse(json);
string[] elementKeys = ((JObject)jsonParsed["element"]).Properties().Select(x => x.Name).ToArray();
List<Samp> data= GetData(((JObject) jsonParsed["samples"]), elementKeys);
public List<Samp> GetData(JObject samples, string[] elementKeys)
{
List<Samp> result = new List<Samp>();
foreach (var element in samples.Properties())
foreach (var item in element.Value)
if ( item["elementKeys"]["H"]!=null
&& item["elementKeys"]["H"].ToObject<string[]>()
.Any(x => elementKeys.Contains(x)) )
result.Add(item.ToObject<Samp>());
return result;
}
classes
public class Samp
{
public string code { get; set; }
public string status { get; set; }
public string bestBy { get; set; }
public string expires { get; set; }
public ElementKeys elementKeys { get; set; }
}
public class ElementKeys
{
public List<string> H { get; set; }
}

What c# model will serialize to a JSON object with dynamic property names each having a list of lists of values?

What data structure/collection in C# that when I serialize using Newtonsoft.Json would give me a result like this, where the property names "data_point1" are dynamic and defined at runtime?
{
"data": {
"data_point1": [
[
string,
string
],
[
string,
string
]
],
"data_point2": [
[
string,
string
],
[
string,
string
]
],
}
}
I tried with List of Dictionaries and it gave result like below:
{
[
{
"data_point1": [
[
string,
string
]
],
"data_point2": [
[
string,
string
]
]
}
]
}
Edit1: changed "Property" to "data_point" as it was confusing. Dataset "data" has thousands of data points, each data point is a collection of data at a specific time.
Edit2: for anyone who this this not real Json, this is from an instruction of a 3rd party API I have to push data to
{
"userToken": "XXXX-XXXX-XXXX-XXXX",
"sessionToken": "XXXX-XXXX-XXXX-XXXX",
"tvqs":
{
"tag1": [ [ "2018-01-09T12:00:00.0000000-05:00", "value" ] ],
"tag2": [
[ "2018-01-09T11:59:55.0000000-05:00", "value" ] ,
[ "2018-01-09T12:00:00.0000000-05:00", "value" ]
]
}
}
You have an array of arrays (jagged array) in each property, you can either use string[][] or List<List<string>> as the type
public class Root
{
public Data data { get; set; }
}
public class Data
{
public List<List<string>> Property1 { get; set; }
public List<List<string>> Property2 { get; set; }
}
If the property names are dynamic, you can use a Dictionary to contain them
public class Root
{
public Data data { get; set; }
}
public class Data
{
public Dictionary<string, List<List<string>>> Properties { get; set; }
}
And the dictionary keys will be Property1, Property2
This can be done as a dictionary with two nested lists inside.
{
//Dictionary
"data": {
// Dictionary Key with value List<List<string>>
"Property1": [
//Entry in List<List<string>>
[
//Entry in List<string>
string,
string
],
[
string,
string
]
],
}
}
using System.Collections.Generic;
var data = new Dictionary<string, List<List<string>>>();

How can I deserialize Array of Arrays in Newtonsoft Json C#? [duplicate]

I have this JSON:
[
{
"Attributes": [
{
"Key": "Name",
"Value": {
"Value": "Acc 1",
"Values": [
"Acc 1"
]
}
},
{
"Key": "Id",
"Value": {
"Value": "1",
"Values": [
"1"
]
}
}
],
"Name": "account",
"Id": "1"
},
{
"Attributes": [
{
"Key": "Name",
"Value": {
"Value": "Acc 2",
"Values": [
"Acc 2"
]
}
},
{
"Key": "Id",
"Value": {
"Value": "2",
"Values": [
"2"
]
}
}
],
"Name": "account",
"Id": "2"
},
{
"Attributes": [
{
"Key": "Name",
"Value": {
"Value": "Acc 3",
"Values": [
"Acc 3"
]
}
},
{
"Key": "Id",
"Value": {
"Value": "3",
"Values": [
"3"
]
}
}
],
"Name": "account",
"Id": "2"
}
]
And I have these classes:
public class RetrieveMultipleResponse
{
public List<Attribute> Attributes { get; set; }
public string Name { get; set; }
public string Id { get; set; }
}
public class Value
{
[JsonProperty("Value")]
public string value { get; set; }
public List<string> Values { get; set; }
}
public class Attribute
{
public string Key { get; set; }
public Value Value { get; set; }
}
I am trying to deserialize the above JSON using the code below:
var objResponse1 = JsonConvert.DeserializeObject<RetrieveMultipleResponse>(JsonStr);
but I am getting this error:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type
'test.Model.RetrieveMultipleResponse' because the type requires a JSON
object (e.g. {"name":"value"}) to deserialize correctly. To fix this
error either change the JSON to a JSON object (e.g. {"name":"value"})
or change the deserialized type to an array or a type that implements
a collection interface (e.g. ICollection, IList) like List that can
be deserialized from a JSON array. JsonArrayAttribute can also be
added to the type to force it to deserialize from a JSON array. Path
'', line 1, position 1.
Your json string is wrapped within square brackets ([]), hence it is interpreted as array instead of single RetrieveMultipleResponse object. Therefore, you need to deserialize it to type collection of RetrieveMultipleResponse, for example :
var objResponse1 =
JsonConvert.DeserializeObject<List<RetrieveMultipleResponse>>(JsonStr);
If one wants to support Generics (in an extension method) this is the pattern...
public static List<T> Deserialize<T>(this string SerializedJSONString)
{
var stuff = JsonConvert.DeserializeObject<List<T>>(SerializedJSONString);
return stuff;
}
It is used like this:
var rc = new MyHttpClient(URL);
//This response is the JSON Array (see posts above)
var response = rc.SendRequest();
var data = response.Deserialize<MyClassType>();
MyClassType looks like this (must match name value pairs of JSON array)
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
public class MyClassType
{
[JsonProperty(PropertyName = "Id")]
public string Id { get; set; }
[JsonProperty(PropertyName = "Name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "Description")]
public string Description { get; set; }
[JsonProperty(PropertyName = "Manager")]
public string Manager { get; set; }
[JsonProperty(PropertyName = "LastUpdate")]
public DateTime LastUpdate { get; set; }
}
Use NUGET to download Newtonsoft.Json add a reference where needed...
using Newtonsoft.Json;
Can't add a comment to the solution but that didn't work for me. The solution that worked for me was to use:
var des = (MyClass)Newtonsoft.Json.JsonConvert.DeserializeObject(response, typeof(MyClass));
return des.data.Count.ToString();
Deserializing JSON array into strongly typed .NET object
Use this, FrontData is JSON string:
var objResponse1 = JsonConvert.DeserializeObject<List<DataTransfer>>(FrontData);
and extract list:
var a = objResponse1[0];
var b = a.CustomerData;
To extract the first element (Key) try this method and it will be the same for the others :
using (var httpClient = new HttpClient())
{
using (var response = await httpClient.GetAsync("Your URL"))
{
var apiResponse = await response.Content.ReadAsStringAsync();
var list = JObject.Parse(apiResponse)["Attributes"].Select(el => new { Key= (string)el["Key"] }).ToList();
var Keys= list.Select(p => p.Key).ToList();
}
}
var objResponse1 =
JsonConvert.DeserializeObject<List<RetrieveMultipleResponse>>(JsonStr);
worked!

Deserialize JSON with $ in property names

I have the following JSON object (the shape of the object will vary hence use of dynamic):
{
"mba$maccType": [{
"class": {
"id": 1057,
"intlId": "cacc"
},
"classA": false,
"endDate": "4712-12-31T00:00:00",
"histStatus": {
"id": 5,
"intlId": "valid"
},
"objClassif": {
"id": 74,
"intlId": "mba$macc_type"
},
"secUser": {
"id": 2
},
"startDate": "2018-12-01T00:00:00",
"timestamp": "2020-01-18T07:29:21"
}
]
}
I'm using Newtonsoft.Json to parse as follows:
dynamic dyn = JObject.Parse(json);
My problem is, I'm unable to reference any dynamic properties because the parent property containing the $ gives a syntax error:
Console.WriteLine(dyn.mba$maccType);
How can I get to the value of "class.intlId" (i.e. "cacc")?
You can parse your JSON to JObject instead of dynamic type and access its items by key. Like get the first item from mba$maccType (since it's an array), then access a class token and intlId value from it
var jObject = JObject.Parse(json);
var firstItem = jObject["mba$maccType"]?.FirstOrDefault();
var result = firstItem?["class"]?["intlId"]?.ToString(); // returns "cacc"
Supposing that the only dynamic part of your JSON structure are the property names on the outer object, you can deserialize this JSON to a Dictionary<string, List<T>>. The benefit of doing this is that you would have clearly defined types for almost everything that's deserialized.
// type definitions
class ClassRecord
{
public int id { get; set; }
public string intlId { get; set; }
}
class Item
{
public ClassRecord #class { get; set; }
public bool classA { get; set; }
// etc.
}
// deserialize
var obj = JsonConvert.DeserializeObject<Dictionary<string, List<Item>>>(json);
Console.WriteLine(obj["mba$maccType"][0].#class.id); // 1057

How to deserialize JSON objects with variable amount of strings?

Below I have a JSON that details an array of objects, each of which have a values property.
This values property is also an object, but each values object may contain any number of strings:
{
"data": [
{
"name": "xxxx",
"values": {
"one": "xxxx",
"two": false
}
},
{
"name": "xxyy",
"values": {
"three": "xxyy",
"four": 1.25,
"five": "xxyy"
}
},
{
"name": "xxyy",
"values": {
"six": "xxyy",
"seven": "xxyyy",
"eight": "xxyy",
"nine": 1234,
"ten": 0
}
}
]
}
Is there a way I can go about deserializing this JSON object so that I'm able to populate a values object, regardless of the number of properties this values object has?
I'm using C# and Newtonsoft.Json to deserialize this.
The below two objects can be used to deserialize the JSON properly:
public class AllData
{
public Item[] Data { get; set; }
}
public class Item
{
public string Name { get; set; }
public IDictionary<string, object> Values { get; set; }
}
And then the following lines can be used to actually do the deserialization:
string json = /*json*/;
AllData data = JsonConvert.DeserializeObject<AllData>(json);

Categories