var stringResult = await HttpHelper.PostAsync(batchUrl, content);
I am getting following result as an API response in C# in above stringResult variable after calling above line. I want to convert below "Items" value to C# list. In every result, first GUID is different. How to convert the below result in C# List. I want only Items.
{
"0934009e-6518-4440-91e3-c252d2e2cc4f": {
"Status": 200,
"Headers": {
"Content-Type": "application/json; charset=utf-8"
},
"Content": {
"Items": [{
"Timestamp": "2021-10-18T14:00:00Z",
"Value": 20.7,
"UnitsAbbreviation": "ppm"
}, {
"Timestamp": "2021-10-25T14:00:00Z",
"Value": 15.9,
"UnitsAbbreviation": "ppm"
}, {
"Timestamp": "2021-11-01T14:00:00Z",
"Value": 14.8,
"UnitsAbbreviation": "ppm"
}, {
"Timestamp": "2021-11-08T15:00:00Z",
"Value": 20.1,
"UnitsAbbreviation": "ppm"
}, {
"Timestamp": "2021-11-15T15:00:00Z",
"Value": 19.5,
"UnitsAbbreviation": "ppm"
}, {
"Timestamp": "2021-11-22T15:00:00Z",
"Value": 19.7,
"UnitsAbbreviation": "ppm"
}, {
"Timestamp": "2021-11-29T15:00:00Z",
"Value": 20.4,
"UnitsAbbreviation": "ppm"
}
]
}
}
}
CodePudding user response:
When some part of the json structure is unknown, you need to explore it manually. There are several ways to do it, but I'm used to passing JObject :
var root = JObject.Parse(text);
// Unknown name property, then iterate
// When the object has one property, First is a good fit
var response = root.First as JProperty;
var guid = response.Name;
var itemsJson = response.Value["Content"]["Items"];
var items = itemsJson.ToObject<List<Item>>();
CodePudding user response:
you can try this code
List<Item> items = JObject.Parse(stringResult).Properties()
.First().Value["Content"]["Items"].ToObject<List<Item>>();
public class Item
{
public DateTime Timestamp { get; set; }
public double Value { get; set; }
public string UnitsAbbreviation { get; set; }
}
CodePudding user response:
go to https://json2csharp.com/
convert your json to C# class.
since your root node is dynamic guid, you cannot directly use class structure deserialization but you can use a inner nodes
Pseudo Program
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
WebClient w = new WebClient();
string json = w.DownloadString(new Uri("https://jsonkeeper.com/b/GETO"));
var firstObject = JObject.Parse(json);
var guid = firstObject.Properties().Select(p => p.Name).FirstOrDefault();
//Console.Write(guid);
Root output = firstObject[guid].ToObject<Root>();
Console.Write(output.Content.Items.Count());
The DTO structure
public class Root
{
public int Status { get; set; }
public Headers Headers { get; set; }
public Content Content { get; set; }
}
public class Content
{
public List<Item> Items { get; set; }
}
public class Headers
{
[JsonProperty("Content-Type")]
public string ContentType { get; set; }
}
public class Item
{
public DateTime Timestamp { get; set; }
public double Value { get; set; }
public string UnitsAbbreviation { get; set; }
}
here's fiddle: https://dotnetfiddle.net/w5fO0w
CodePudding user response:
I have used below code to get items -
var resultObjects = AllChildren(JObject.Parse(json))
.First(c => c.Type == JTokenType.Array )
.Children<JObject>();
foreach (JObject result in resultObjects)
{
foreach (JProperty property in result.Properties())
{
}
}
And method is -
private static IEnumerable<JToken> AllChildren(JToken json)
{
foreach (var c in json.Children())
{
yield return c;
foreach (var cc in AllChildren(c))
{
yield return cc;
}
}
}