How to use Json.NET, how can I parse a list of objects with dynamic names into a list?

The following is an example of the JSON format that I get from an external API:

"object": { "property_1": { "values": { "value": 1, "displayValue": "1" } }, "property_5": { "values": { "value": 3, "displayValue": "3" } }, "property_8": { "values": { "value": 1, "displayValue": "1" } }, "property_14": { "values": { "value": 392, "displayValue": "392.0" } }, "property_17": { "values": { "value": 14, "displayValue": "14" } } } 

There are about 100 different types of properties that can be sent, but they all follow the same structure. The only difference is the name of the property ("property_1", "property_5", etc.). Instead of trying to write a class with a long list of properties that are not always used, I think it would be much more useful to parse this into a list of objects using the property name in the resulting class as follows:

 public class Property { public string Name { get; set; } public PropertyValues Values { get; set; } } public class PropertyValues { public double Value { get; set; } public string DisplayValue { get; set; } } 

In this case, the name of the property ("property_1", "property_5", etc.) will be assigned to the Name field in the Property object.

How can this be done using Json.NET?

+5
source share
2 answers
 var result = JsonConvert.DeserializeObject<Root>(json); 

Model below


 public class Root { public Dictionary<string, ValueWrapper> Object { get; set; } } public class ValueWrapper { public PropertyValues Values { get; set; } } public class PropertyValues { public int Value { get; set; } public string DisplayValue { get; set; } } 

BTW: Json.Net can work with dynamics easier than @ MatíasFidemraizer suggested ...

 var val = ((dynamic)JsonConvert.DeserializeObject(jsonstring)) .@object.property _14.values.value; var val = ((dynamic)JsonConvert.DeserializeObject(jsonstring)) .@object ["property_14"].values.value; 

But this approach will require you to know that property_14 will be returned by your server in advance ...

+10
source

There is another approach: you can use expando objects :

 dynamic response = JsonConvert.DeserializeObject<ExpandoObject>("JSON TEXT", new ExpandoObjectConverter()); 

And you can access the properties using dynamic input:

 long someValue = response.@object.property _1.values.value; 

In addition, since ExpandoObject implements IDictionary<string, object> , you can use it as a dictionary and check if the property exists:

 if(((IDictionary<string, object>) response.@object ).ContainsKey("property_1")) { } 

It seems that you are going to save a lot of time along the way!

Answer to this answer

It seems that most of the hate in my answer is focused on this @EZI comment:

And let you not know property_14 before json deserialization.

And another @LB responder claims this in his own answer:

But this approach will require you to know that property_14 will be returned by your server in advance ...

In my case, I believe this problem is already resolved in my answer when I mention that ExpandoObject implements IDictionary<string, object> . You may not know that property_14 will be part of a deserialized object graph. No problem :

 if(((IDictionary<string, object>) response.@object ).ContainsKey("property_14")) { // You've already addressed the issue, because you won't get a // run-time exception since you'll access such property if it already // in the returned response... object property_14 = response.@object.property _14; } 
+2
source

Source: https://habr.com/ru/post/1260018/


All Articles