问题
{
"TestData":{
"Year__of__Account":"2019",
"Tax___x0025_":"0.06",
"Buildings__1":"1000",
"Contents__1":"400",
"Total_Insurable_Value":"100",
"Buildings__Prem":"2560.8",
"Contents__Prem":"1707.2",
"YB__1":"1950",
"No__Buildings":"55",
"Location_Sprinklers_YN":"No",
"test":"test"
}
}
In the above sample JSON I want to add a property called "Name" with Value "John" inside property "TestData". How can I achieve this using .net Core 3.0 System.Text.Json library.
I have tried using methods of Utf8JsonWriter but it is creating a new JSON object instead of appending it to the above existing JSON.
using (MemoryStream memoryStream1 = new MemoryStream())
{
using (Utf8JsonWriter utf8JsonWriter1 = new Utf8JsonWriter(memoryStream1))
{
using (JsonDocument jsonDocument = JsonDocument.Parse(json))
{
utf8JsonWriter1.WriteStartObject();
utf8JsonWriter1.WritePropertyName("Name");
utf8JsonWriter1.WriteStringValue("John");
utf8JsonWriter1.WriteEndObject();
// how can I add above properties to JsonDocument object??
}
}
}
回答1:
Assuming there may be several properties and you want to add a name only to "TestData" property:
using (MemoryStream memoryStream1 = new MemoryStream())
{
using (Utf8JsonWriter utf8JsonWriter1 = new Utf8JsonWriter(memoryStream1))
{
using (JsonDocument jsonDocument = JsonDocument.Parse(json))
{
utf8JsonWriter1.WriteStartObject();
foreach (var element in jsonDocument.RootElement.EnumerateObject())
{
if (element.Name == "TestData")
{
utf8JsonWriter1.WritePropertyName(element.Name);
// Staring new object
utf8JsonWriter1.WriteStartObject();
// Adding "Name" property
utf8JsonWriter1.WritePropertyName("Name");
utf8JsonWriter1.WriteStringValue("John");
// Copying existing values from "TestData" object
foreach (var testDataElement in element.Value.EnumerateObject())
{
testDataElement.WriteTo(utf8JsonWriter1);
}
utf8JsonWriter1.WriteEndObject();
}
else
{
element.WriteTo(utf8JsonWriter1);
}
}
utf8JsonWriter1.WriteEndObject();
}
}
var resultJson = Encoding.UTF8.GetString(memoryStream1.ToArray());
}
Here for each property (except for "TestData" property) I write the whole value as is (by calling element.WriteTo(utf8JsonWriter1)
), and for "TestData" property I start a new object, add "Name" property and then copy each of the "TestData" object's properties.
P.S. This works, but I'm pretty sure a much better solution should exist.
回答2:
Here is a possible answer
static void Main(string[] args)
{
var jsonString = @"
{
""TestData"":{
""Year__of__Account"":""2019"",
""Tax___x0025_"":""0.06"",
""Buildings__1"":""1000"",
""Contents__1"":""400"",
""Total_Insurable_Value"":""100"",
""Buildings__Prem"":""2560.8"",
""Contents__Prem"":""1707.2"",
""YB__1"":""1950"",
""No__Buildings"":""55"",
""Location_Sprinklers_YN"":""No"",
""test"":""test""
}
}
";
var jsonDoc = JsonSerializer.Deserialize<Dictionary<string, object>>(jsonString);
var testDataDict = JsonSerializer.Deserialize<Dictionary<string, object>>(jsonDoc["TestData"].ToString());
testDataDict.Add("Name", "John");
//replace the test data with the modified test data
jsonDoc["TestData"] = testDataDict;
Console.WriteLine(JsonSerializer.Serialize(jsonDoc));
}
回答3:
I've just created a NuGet package with some hopefully useful extension methods for JsonElement, which allow properties to be added and/or removed. It's based on using the Utf8JsonWriter to create a new mutated JsonElement based on the original, like the answer above.
GitHub repo | NuGet package
var jsonString = "{ \"Name\": \"Andrew\", \"EmailAddress\": \"a@b.com\" }";
var jElement = JsonDocument.Parse(jsonString).RootElement;
jElement = jElementAddProperty("Age", 38)
.AddProperty("Male", true)
.AddProperty("Female", false)
.AddNullProperty("Alien")
.AddProperty("Roles", new string[] { "admin", "user" })
.AddProperty("LastUpdated", DateTime.UtcNow)
.AddProperty("crazyNewObject", new
{
Name = "Hobbies",
Value = "bass guitar and writing c# code"
});
Hopefully someone will find them useful, but if they don't do quite what you need, please enhance and submit a pull request.
回答4:
Using JsonSerializer to deserialize into a nested dictionary is also possible:
static void Main(string[] args)
{
string testJson = @"
{
""TestData"":{
""Year__of__Account"":""2019"",
""Tax___x0025_"":""0.06"",
""Buildings__1"":""1000"",
""Contents__1"":""400"",
""Total_Insurable_Value"":""100"",
""Buildings__Prem"":""2560.8"",
""Contents__Prem"":""1707.2"",
""YB__1"":""1950"",
""No__Buildings"":""55"",
""Location_Sprinklers_YN"":""No"",
""test"":""test""
}
}";
using (var memoryStream1 = new MemoryStream())
{
using (var utf8JsonWriter1 = new Utf8JsonWriter(memoryStream1))
{
//For each level in json tree an additional dictionary must be added
var jsonDict = JsonSerializer.Deserialize<Dictionary<string, Dictionary<string, object>>>(testJson);
jsonDict["TestData"].Add("Name", "John");
JsonSerializer.Serialize<object>(utf8JsonWriter1, jsonDict);
}
string testString = Encoding.UTF8.GetString(memoryStream1.ToArray());
}
}
But note that the new property is always added at the end of the TestData block.
来源:https://stackoverflow.com/questions/58302522/how-to-add-property-in-existing-json-using-system-text-json-library