Description
Description
Assigning a JsonNode
to the same parent again throws an exception stating that the node already has a parent. If it would be re-parented then this would be expected. But if the new parent is old parent, then this should not fail but treat it as a no-op.
In local code this is no problem, because then you just refactor the assignment. But if you do a library and let the developer return a transformed or - as in our case - the original JsonNode
, then this is problematic, because now you have to check for reference equality and avoid the assignment.
Investigation
This is the involved code:
calling
AssignParent
which throws an exception if parent has any value (even if it is the same):runtime/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonNode.cs
Lines 346 to 349 in be6d8d0
For properties of JsonObject
this seems to be no problem as the following code does not throw:
var obj = new JsonObject();
var node = JsonValue.Create(1);
obj["child"] = node;
obj["child"] = node; // no exception 👍
Those two behaviors are different but the JsonObject
property no-op assignment behavior makes sense.
Reproduction Steps
var array = new JsonArray();
var node= JsonValue.Create(1); // or new JsonObject();
array.Add(node);
array[0] = node; // throws "System.InvalidOperationException: 'The node already has a parent.'"
Expected behavior
No exception should be thrown - effectivly a no-op.
Actual behavior
Throws exception
System.InvalidOperationException: 'The node already has a parent.'
Regression?
Unknown
Known Workarounds
This is a undesirable workaround. Instead of just writing
var array = new JsonArray();
var node = new JsonObject();
array.Add(node);
...
// somewhere later on
array[0] = SomeCodeReturningANewOrSameJsonNode(node);
one needs to carefully write
var array = new JsonArray();
var node = new JsonObject();
array.Add(node);
...
// somewhere later on
var temp = SomeCodeReturningANewOrSameJsonNode(array[0]);
if (!ReferenceEquals(array[0], temp))
{
array[0] = temp;
}
Configuration
.NET 9
Windows 11
Other information
No response