如何使用System.Text.Json库在现有json中添加属性?

时间:2019-10-09 10:51:57

标签: c# json .net-core-3.0 system.text.json

       {
          "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"
           }
        }

在上面的示例JSON中,我想在属性“ TestData”内添加一个名为“ Name”的属性,其值为“ John”。如何使用.net Core 3.0 System.Text.Json库实现此目的。

我尝试使用Utf8JsonWriter的方法,但是它正在创建一个新的JSON对象,而不是将其附加到上面的现有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??
                }
            }
        }

4 个答案:

答案 0 :(得分:2)

假设可能有多个属性,并且您只想为“ TestData”属性添加名称:

let u0 = User()
u0.uid = u0.getNextUid()
u0.username = "User 0"

let realm = try! Realm()
try! realm.write {
    realm.add(u0)
}

let u1 = User()
u1.uid = u1.getNextUid()
u1.username = "User 1"

try! realm.write {
    realm.add(u1)
}

在这里,对于每个属性(“ TestData”属性除外),我照原样写整个值(通过调用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()); } ),对于“ TestData”属性,我启动一个新对象,添加“ Name”属性,然后然后复制每个“ TestData”对象的属性。

P.S。可以,但是我很确定应该有更好的解决方案。

答案 1 :(得分:2)

这是一个可能的答案

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));
    }

答案 2 :(得分:1)

我刚刚创建了一个NuGet包,其中包含一些希望有用的JsonElement扩展方法,这些扩展方法允许添加和/或删除属性。它是基于使用Utf8JsonWriter创建基于原始变量的新突变JsonElement的,就像上面的答案一样。

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"
});

希望有人会发现它们有用,但是如果他们做不到您所需要的,请增强并提交拉取请求。

答案 3 :(得分:0)

还可以使用JsonSerializer反序列化为嵌套字典:

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());
    }
}

但是请注意,新属性始终添加在TestData块的末尾。