0

I'm able to get a dynamic Json object using

dynamic obj = JsonConvert.DeserializeObject(json);

It seems to be a nested object structure

I need to graph every variable in the json file, but the json file structure changes often

Is there a way to parse through this structure using nested foreach() statements? If not, can can I parse it by accessing each element via a string like a Dictionary?

for example something like:

if(obj["Item1"]["Parameter3"]["Value2"]` != NULL)
   int number = obj["Item1"]["Parameter3"]["Value2"]`

Thanks,

Mich
  • 3,188
  • 4
  • 37
  • 85
  • Possible duplicate of [How to do recursive descent of JSON using Json.Net?](https://stackoverflow.com/q/16181298/10263) or maybe [Generically Flatten Json using c#](https://stackoverflow.com/q/32782937/10263) – Brian Rogers Aug 27 '19 at 20:25

2 Answers2

1

Yes there is an API for querying dynamically. See the documentation here: https://www.newtonsoft.com/json/help/html/QueryingLINQtoJSON.htm

Code looks something like this:

JObject rss = JObject.Parse(json); 
var postTitles =
    from p in rss["channel"]["item"]
    select (string)p["title"];
Tim
  • 2,878
  • 1
  • 14
  • 19
0

Finally figured this api out

Some JToken entries have a list of values, others have a name and value. You have to sort which one is which prior to parsing it.

This will create a Dictionary with every entry in the Json file

    void SomeFunction()
    {
        Dictionary<string, decimal> json_data = new Dictionary<string, decimal>();
        dynamic json_obj = JsonConvert.DeserializeObject(json);
        Linearize(ref json_data, json_obj);
    }

    void Linearize(ref Dictionary<string, decimal> input_dict, JToken json_data, string key = "")
    {
        int i;
        if (json_data != null)
        {
            if (json_data.HasValues)
            {
                i = 0;
                foreach (dynamic entry in json_data)
                {
                    //Add a Name field if it exists
                    Type typeOfDynamic = entry.GetType();
                    if (typeOfDynamic.GetProperties().Where(p => p.Name.Equals("Name")).Any())
                        key += entry.Name + ".";

                    //If JToken is an Array
                    if (((JToken)entry).HasValues)
                    {
                        Linearize(ref input_dict, entry, key + "[" + i++ + "]" + ".");
                    }

                    //If JToken is a data type
                    else if (entry.Type == JTokenType.String || entry.Type == JTokenType.Float || entry.Type == JTokenType.Integer)
                    {
                        decimal output;
                        if (decimal.TryParse(entry.ToString(), out output))
                            input_dict.Add(key + "[" + i++ + "]", output);
                    }
                }
            }
        }           
    }
Mich
  • 3,188
  • 4
  • 37
  • 85
  • You shouldn't have to resort to reflection, or dynamics to accomplish what you are wanting to do. It's a bit like using a nuke to hammer in a nail. There's a type on every jtoken indicating if it is an array, something atomic (a value), or an Array. You can use that to iterate over all children. And you can query the jtokens to see if you have a name property instead of adding reflection. If the JToken happens to be a JObject you can get all properties easily https://www.newtonsoft.com/json/help/html/JObjectProperties.htm – Tim Aug 28 '19 at 02:16