SaiV
SaiV

Reputation: 53

How to add a JObject inside an existing JArray?

My Jobject is as below:

JObject sampleObj = "{
      "operator": "AND",
      "rules": [
        {
          "field": "Entity.Country",
          "condition": "=",
          "value": "'USA'"
        },
        {
          "field": "Entity.ShortName",
          "condition": "=",
          "value": "'Adele'"
        }
      ]
    }"

How do I add another JObject inside the JArray "rules" in the JSON? like below

    JObject Parent  =
          "{
    "operator": "AND",
    "rules": [{
            "field": "Entity.Country",
            "condition": "=",
            "value": "'USA'"
        },
        {
            "field": "Entity.ShortName",
            "condition": "=",
            "value": "'Adele'"
        },
        {
            "operator": "AND",
            "rules": [{
                    "field": "Entity.Country",
                    "condition": "=",
                    "value": "'USA'"
                },
                {
                    "field": "Entity.ShortName",
                    "condition": "=",
                    "value": "'Adele'"
                }
            ]
        }
    ]
}" 

I tried:

Parent["rules"].Add(sampleObj);
Parent.selectToken("rules").Add(sampleObj);

But, intellisense do not allow me do that. Working on C# + Newtonsoft.Json libraries:

'JToken' does not contain a definition for 'Add' and no accessible extension method 'Add' accepting a first argument of type 'JToken' could be found (are you missing a using directive or an assembly reference?)  

Upvotes: 2

Views: 3560

Answers (1)

dbc
dbc

Reputation: 117046

Your problem is that the accessor method JObject.Item Property (String), used in Parent["rules"].Add(sampleObj), returns a JToken, which is the abstract base class for all possible JSON values -- primitive or non-primitive. As such it has no Add() method, because the derived class JValue representing a primitive value has no Add() method.

Thus you will need to cast Parent["rules"] to its actual type, which is JArray, in order to add an array item:

((JArray)Parent["rules"]).Add(sampleObj);

If you think it looks cleaner, you can use JToken.Value<T>(Object key) instead of an inline cast, which does the same thing:

Parent.Value<JArray>("rules").Add(sampleObj);

Or, if there's a chance that the "rules" array hasn't been created yet:

var array = Parent.Value<JArray>("rules") ?? (JArray)(Parent["rules"] = new JArray());
array.Add(sampleObj);

Similarly, JToken.SelectToken Method (String) returns a JToken and so casting is also required.

Related:

Demo fiddle here.

Upvotes: 1

Related Questions