1

I am working with Jsons which I don't know their structure in advanced. Just for example:

{
    "OrganizationData": {
        "Org1": {
            "Name": "Rega And Dodli",
            "EmployessNum": "100000000"
         },
         "Org2": {
            "Name": "Sami And Soso",
            "EmployessNum": "2"
         }
    }
}

I'm currently getting values by using the SelectToken method to which I can pass a key with a sub key like this:

var token = myJObject.SelectToken("OrganizationData.Org1")

This works fine. Now I want to add a new entry to the JSON using a string like that, something like:

myJObject.Add("OrganizationData.Org3", myValueJson);

but calling add like that directly just adds a new key to the json called "OrganizationData.Org3" and not creating a new sub key called "Org3" inside "OrganizationData" like the current "Org1" and "Org2".

How can I add a new value with a delimited string like needed?

CodeMonkey
  • 11,196
  • 30
  • 112
  • 203

1 Answers1

0

JSON doesn't have subkeys or delimited keys. OrganizationData.Org1 is a LINQ to JSON search expression, not a subkey.

To add Org3 you can use one of the many ways available to modify a JSON object. You can add a child element to OrganizationData or a sibling to one of the other Org nodes.

To add a child element to a node, you could use .SelectToken("OrganizationData") if you don't already have a reference to it, and use JObject.Add to add the new node. You'll have to cast the result to JObject first, as SelectToken returns a JToken. If there's a chance that OrganizationData is an array, you'll have to check the type too.

For example:

var token = myJObject.SelectToken("OrganizationData");
if(token is JObject orgObj)
{
    orgObj.Add("Org3",myValueJson);
}

Working with unknown paths

The same thing works if the path is specified at runtime. In this case, all that's needed is to separate the last part from the rest of the path, perhaps using String.LastIndexOf`:

var lastDot=path.LastIndexOf('.');
if (lastDot<0)
{
    //Oops! There's no dot. What do we do now?
}
var parent=path.Substring(0,lastDot);
var key=path.Substring(lastDot+1);

var token = myJObject.SelectToken(parent);
if(token is JObject orgObj)
{
    orgObj.Add(key,myValueJson);
}

You'll have to decide what to do if the path contains no dot. Is this an invalid path? Or should a new object be added under the root object?

Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
  • I don't know the structure of the json in advanced. All I have is a full string of some json I know nothing about and a key like "key1.key2.key3" and I need to add a new jobject to that path – CodeMonkey Oct 12 '20 at 08:13
  • You know enough already - that `OrganizationData` is an object, containing properties, not an array or a value. Knowing the path means you *can* check if that object exists and if not, find the parent specified in the path, and insert the new object. All you need to do is split the path – Panagiotis Kanavos Oct 12 '20 at 08:17
  • I don't know that there is something called "OrganizationData". It was just an example of a json to show what I want to do – CodeMonkey Oct 12 '20 at 08:20
  • You know there is a parent path in there and a new item name. I posted how to extract them with `String.LastIndexOf` – Panagiotis Kanavos Oct 12 '20 at 08:24
  • OK that can work. but isn't there something built in that I can use without the need to parse the path? – CodeMonkey Oct 12 '20 at 08:35
  • Why are you asking? The code is trivial and one could argue that what you ask is specific to your application. *Patching* an existing document on the other hand is far more common and a lot trickier, so it's supported eg by [PopulateObject](https://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_JsonConvert_PopulateObject.htm). An example is shown in [Modify existing object with new partial JSON data using Json.NET](https://stackoverflow.com/questions/27511675/modify-existing-object-with-new-partial-json-data-using-json-net) – Panagiotis Kanavos Oct 12 '20 at 08:52