1

Below is my JSON:

[
  {
    "name": "Node-1",
    "flag": true,
    "myObj": {
      region: {
        info: {
          name: null,
          infoFlag: false,

        }
      }
    },
    "nodes": [
      {
        "name": "Node-1-1",
        "flag": true,
        "myObj": {
          region: {
            info: {
              name: "abc",
              infoFlag: false,

            }
          }
        },
        "nodes": [
          {
            "name": "Node-1-1-1",
            "flag": true,
            "myObj": {
              region: {
                info: {
                  name: "xyz",
                  infoFlag: false,

                }
              }
            },
            "nodes": [

            ]
          }
        ]
      }
    ]
  }
]

I want to update two properties of my above JSON string with following rule :

Flag : I want to blindly update this property to false.

infoFlag: If name property of info is null then I want to update infoFlag to true else false if it is not null.

So after updating my JSON with these rules I want to have that JSON as a string.

Note: I don't want to deserialize and then update property based on above two rules as because my JSON has lots of properties for which I don't want to create classes, so I am looking for something which will work without deserializing with class.

This is how I am trying to do it:

string json = "MyJson";
var temp =  JArray.Parse(json);
temp.Descendants()
    .OfType<JProperty>()
json = temp.ToString();

But here I am not getting as how to traverse my JSON recursively; as you can see I have recursive structure like below :

Node-1
    Node-1-1
       Node-1-1-1
5
  • 1
    Possible duplicate of Deserialize json object into dynamic object using Json.net Commented Sep 21, 2017 at 8:18
  • 1
    You can deserialize without having to declare classes. The alertnative is to not deserialize at all, but then you'd have to write a really smart parser. Commented Sep 21, 2017 at 8:19
  • 1
    @GolezTrol Main objective of asking this question was how to locate and update property value without having deserialization in to class.I very well know this how to deserialize json string in to dynamic object :) Commented Sep 21, 2017 at 9:56
  • Then why do you say "has lots of properties for which i dont want to create classes". Using a dynamic object you can do exactly that. JArray.Parse you deserialize as well. If you want to replace properties without deserializing at all, you're gonna have to stick to String.Replace or some regex magic, but I'm sure you don't want to go down that road. Commented Sep 21, 2017 at 10:18
  • @GolezTrol Its ok to deserialize in to any dynamic object but i was just saying i dont want to deserialize in to any class because i dont want to create class to handle this deserialization.Moreover the part which i am struggling is to manipulate those properties after deserializing in to dynamic object. Commented Sep 21, 2017 at 10:21

2 Answers 2

2

Json.NET allows you to treat its internal objects representing the JSON content as dynamic, which makes the task in question no harder than using regular typed objects.

The only kind of tough problem is the recursive object structure (the nodes array), but that's not a JSON or dynamic specific problem, and can be solved in many ways - the obvious recursive method or with my preferable tree flattening enumeration (the Expand method from my answer to How to flatten tree via LINQ?).

With that being said, the solution could be like this:

var array = JArray.Parse(json);
var nodes = array.Cast<dynamic>().Expand(x => x.nodes);
foreach (var node in nodes)
{
    node.flag = true;
    var info = node.myObj.region.info;
    info.infoFlag = (info.name == null);
}
var newJson = array.ToString();
Sign up to request clarification or add additional context in comments.

2 Comments

This is really really beautifull :)
This worked.Thank you so much and please continue giving genius and brilliant answers like this like as usual :)
2

If I have understood your needs this code is pretty verbose and not so elegant but works:

    JArray temp =  JArray.Parse(json);

    foreach (JToken tk in temp.Descendants())
    {
        if (tk.Type == JTokenType.Property)
        {
            JProperty p = tk as JProperty;

            if (p.Name == "flag")
            {
                if ((bool)p.Value.ToObject(typeof(bool)) == true)
                    p.Value = false;
            }

            if ((p.Name == "info") && p.HasValues)
            {
                bool flag = false;

                foreach (JToken tkk in p.Descendants())
                {
                    if (tkk.Type == JTokenType.Property)
                    {
                        JProperty pp = tkk as JProperty;

                        if ((pp.Name == "name") && (pp.Value.Type == JTokenType.Null))
                        {
                            flag = true;
                        }

                        if ((pp.Name == "infoFlag"))
                        {
                            pp.Value = (flag == true) ? true : false;
                        }
                    }
                }
            }
        }
    }

    json = temp.ToString();

This is the resulting output:

[
  {
    "name": "Node-1",
    "flag": false,
    "myObj": {
      "region": {
        "info": {
          "name": null,
          "infoFlag": true
        }
      }
    },
    "nodes": [
      {
        "name": "Node-1-1",
        "flag": false,
        "myObj": {
          "region": {
            "info": {
              "name": "abc",
              "infoFlag": false
            }
          }
        },
        "nodes": [
          {
            "name": "Node-1-1-1",
            "flag": false,
            "myObj": {
              "region": {
                "info": {
                  "name": "xyz",
                  "infoFlag": false
                }
              }
            },
            "nodes": []
          }
        ]
      }
    ]
  }
]

1 Comment

Upvoted for your kind efforts towards helping me.Appreciated :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.