Home > Software design >  How to copy a JSON value using .NET 6 JsonNode System.Text.Json.Nodes?
How to copy a JSON value using .NET 6 JsonNode System.Text.Json.Nodes?

Time:02-17

I have a simple JSON I would like to rename (probably by copying then removing) a key. .NET Fiddle:

        const string input = @"{ ""foo"": [{""a"": 1}, {""b"": null}] }";
        var node = JsonNode.Parse(input);
        Console.WriteLine(node); // Output: the JSON
        Console.WriteLine(node["foo"][0]["a"]); // Output: 1
        
        // How to copy/rename?
        node["bar"] = node["foo"];
        Console.WriteLine(node["bar"][0]["a"]); // Should be 1
{
  "foo": [
    {
      "a": 1
    },
    {
      "b": null
    }
  ]
}

How do I copy/rename it? I tried using node["foo"].AsValue() but it doesn't work as well. The error is

The node must be of type 'JsonValue'


I just found a workaround by converting to JSON string and parsing it again but I hope there is a better way to do it.

node["bar"] = JsonNode.Parse(node["foo"].ToJsonString());

CodePudding user response:

Your question update adds "bar" to an existing node object. if you want to create a new object that is a copy of an existing node object, you can make it 2 main ways

  1. The simpliest and most efficient way is to change json string
    string newInput = input.Clone().ToString().Replace("\"foo\":","\"bar\":");
    var newNode=JsonNode.Parse(newInput);
  1. Or create new json object
var newNode = new JsonObject( new[] { KeyValuePair.Create<string,JsonNode>("bar", 
               JsonNode.Parse(node["foo"].ToJsonString()) )});

result

{
  "bar": [
    {
      "a": 1
    },
    {
      "b": null
    }
  ]
}

CodePudding user response:

So what you have is a JSON object, so JsonNode.Parse will really return a JsonObject, so first we need to cast it:

var jsonObject = JsonNode.Parse(input)!.AsObject(); // null check omitted for brevity

Now let's do the rename. A rename is really a removal of the object with the old property followed by readding it with the new name. So:

var node = jsonObject["foo"]; // take a reference to foo so we don't lose it
jsonObject.Remove("foo"); // detach from parent
jsonObject.Add("bar", node); // attach with new name

The reason why you need to first remove it and then add it back, is that JsonNode objects have parents, and you're not allowed to add a node to an object or array if it already has a parent. So you first need to detach it from its parent with Remove, and then you can add it back under the new name with Add.

  • Related