I have a JSON text:
{
"a": [{
"a1": "string",
"a2": "string",
"a3": "string"
}
],
"b": "2021-12-29T14:20:21.948Z",
"c": {
"c1": [{
"c11": "string",
"c12": "string",
"c13": "string",
"c14": true,
"c15": true,
"c16": "2021-12-29T14:20:21.948Z",
"c17": "string"
}
]
}
}
JsonNode class always has a unique path I want to use them to find a specific value (update/delete them).
So, I want to use System.Text.Json and .NET 6 to have the following methods:
public static JsonNode UpdateValue(string json /*JsonNode json*/, string path, object value)
{
// ?
}
public static JsonNode RemovePath(string json /*JsonNode json*/, string path)
{
// ?
}
Is it possible?
CodePudding user response:
In short: Unfortunately you can't
Modification
JsonDocument is readonly by design. Before JsonNode has been introduced you had to
- deserialize it as
Dictionary<string, object> - perform the modification
- serialize it back to json
Since JsonNode has been introduced in .NET 6 you can do the following
var node = JsonNode.Parse(json);
var rootObject = node as JsonObject;
var aArray = rootObject["a"] as JsonArray;
var firstA = aArray[0];
firstA["a3"] = "modified";
or in short
var node = JsonNode.Parse(json);
node["a"][0]["a3"] = "modified";
Locate element by Path
Even though the need has been expressed in 2019 it hasn't been address yet. But as layomia said
This feature is proposed for .NET 6, but not committed. To be clear, we acknowledge that this is an important feature for many users, however, work on features with higher priority may prevent this from coming in .NET 6.
Unfortunately this feature did not make it to the .NET 6.
There are 3rd party libraries which offers this capability for JsonDocument. One of the most mature one is called JsonDocumentPath. With its SelectElement method you can really easily retrieve the given field as JsonElement
var doc = JsonDocument.Parse(json);
JsonElement? a3 = doc.RootElement.SelectElement("$.a[0].a3");
Interoperability
Even though there is a way to convert JsonElement to JsonNode and in the other way around:
var a3Node = JsonSerializer.Deserialize<JsonNode>(a3.Value);
a3Node = "a";
it does not really help since the a3Node represents only the a3 field and according to my understanding you can't just merge two JsonNodes.
CodePudding user response:
update json using Newtonsoft.Json
string json = File.ReadAllText("json");
dynamic jsonObj = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
jsonObj["a"][0]["test1"] = "new values";
string output = Newtonsoft.Json.JsonConvert.SerializeObject(jsonObj, Newtonsoft.Json.Formatting.Indented);

