在C#中向现有JSON字符串添加另一个JSON字符串

5

我试图将一个JSON字符串添加到一个已存在的字符串中,但一直无法成功实现。

这是原始字符串:originalJSONString

{
  "properties": [
    "property1",
    "property2"
  ]
}

我想把这个字符串加入到原始字符串中:JSONStringIwantToAdd

{
  "filter": {
    "Name": "some filter name",
    "Parameters": {
      "LookupKey": "somekey",
      "LookupValue": "somevalue"
    }
  }
}

为了生成类似这样的结果字符串:finalJSONString
{
  "properties": [
    "property1",
    "property2"
  ],
  "filter": {
    "Name": "some filter name",
    "Parameters": {
      "LookupKey": "somekey",
      "LookupValue": "somevalue"
    }
  }
}

目前这是我的方向,但在propertiesJObject中我得到了null,之后就无法弄清楚了。

我是否走对了方向?

        var originalJObj = JObject.Parse(originalJSONString);
        var tobeaddedJObj = JObject.Parse(JSONStringIwantToAdd);
        var propertiesJObject = originalJObj["properties"] as JObject;
        propertiesJObject.Add(tobeaddedJObj);
        var serializer = new JsonSerializer { ContractResolver = new CamelCasePropertyNamesContractResolver() };
        var finalJSONString = JObject.FromObject(originalJObj, serializer).ToString();

有人能帮我解决这个问题吗?

谢谢您的时间!


1
propertiesJObject 为 null 是因为它是一个 JArray 而不是一个 JObject。当你使用 as JObject 时,如果强制转换失败,as 将返回 null。 - Nate Barbettini
4个回答

4

JSON.NET 包含了你需要的功能: JContainer.Merge

请注意,Merge 会修改原始对象,而不是返回新对象:

var original = JObject.Parse(@"{
  ""properties"": [
    ""property1"",
    ""property2""
  ]
}");

var toAdd = JObject.Parse(@"{
  ""filter"": {
    ""Name"": ""some filter name"",
    ""Parameters"": {
      ""LookupKey"": ""somekey"",
      ""LookupValue"": ""somevalue""
    }
  }
}");

original.Merge(toAdd, new JsonMergeSettings
{
    // union array values together to avoid duplicates
    MergeArrayHandling = MergeArrayHandling.Union
});

示例链接:https://dotnetfiddle.net/o51GuA


这是最简单的方法,所以我将其标记为答案。 - Ash K

3

您可以不必明确使用序列化程序即可完成此操作。

此代码将 JSONStringIwantToAdd 的第一个属性添加到 originalJSONString 中:

var originalJson = "{\r\n  \"properties\": [\r\n    \"property1\",\r\n    \"property2\"\r\n  ]\r\n}";

var extraJson = "{\r\n  \"filter\": {\r\n    \"Name\": \"some filter name\",\r\n    \"Parameters\": {\r\n      \"LookupKey\": \"somekey\",\r\n      \"LookupValue\": \"somevalue\"\r\n    }\r\n  }\r\n}";

var original = JObject.Parse(originalJson);
var extra = JObject.Parse(extraJson);
var newProperty = extra.Children().First() as JProperty;

original.Add(newProperty.Name, newProperty.Value);

var newJson = original.ToString();

输出:

{
  "properties": [
    "property1",
    "property2"
  ],
  "filter": {
    "Name": "some filter name",
    "Parameters": {
      "LookupKey": "somekey",
      "LookupValue": "somevalue"
    }
  }
}

1
非常感谢,这是一个相当聪明的做法。我会将@Nate的答案标记为最短的方法。 - Ash K
2
@Nate的答案看起来非常像解决您特定问题的最佳方法,但我将其保留在此处,以防它能帮助其他遇到类似问题且JContainer.Merge不可行的人。 - stuartd
1
是的,如果“合并”不完全符合您的要求,这是一个很好的方法。 - Nate Barbettini

0

这应该可以工作,主要问题是在将过滤器属性添加到jobject时未访问该属性。 我建议添加一些保障措施,例如检查现有属性,这可能不是最高效的方式。 如果速度很重要,则可能需要为Json.net编写自己的序列化程序/反序列化程序。

    [Test]
    public void AugmentJsonObjectTest()
    {
        // Given
        var originalString = "{  \"properties\": [    \"property1\",    \"property2\"  ]}";
        var stringToBeAdded = "{  \"filter\": {    \"Name\": \"some filter name\",    \"Parameters\": {      \"LookupKey\": \"somekey\",      \"LookupValue\": \"somevalue\"    }  }}";

        // When
        var originalObject = JObject.Parse(originalString);
        var objectToBeAdded = JObject.Parse(stringToBeAdded);
        originalObject.Add("filter", objectToBeAdded["filter"]);
        var mergedObjectAsString = originalObject.ToString();

        // Then
        var expectedResult =
            "{  \"properties\": [    \"property1\",    \"property2\"  ],  \"filter\": {    \"Name\": \"some filter name\",    \"Parameters\": {      \"LookupKey\": \"somekey\",      \"LookupValue\": \"somevalue\"    }  }}";
        // Parsing and toString to avoid any formatting issues
        Assert.AreEqual(JObject.Parse(expectedResult).ToString(), mergedObjectAsString);
    }

1
非常感谢。我将标记@Nate的答案,因为这是做这件事最简短的方法。 - Ash K

0
使用 Expando
using System.Collections.Generic;
using System.Dynamic;
using System.IO;
using Newtonsoft.Json;

namespace jsonConcat {
class Program {
    static void Main (string[] args) {
        ExpandoObject inputData;
        ExpandoObject appendData;
        using (TextReader inputReader = new StreamReader ("originalData.json"))
        using (TextReader appendReader = new StreamReader ("appendData.json")) {
            inputData = JsonConvert.DeserializeObject<ExpandoObject> (inputReader.ReadToEnd ());
            appendData = JsonConvert.DeserializeObject<ExpandoObject> (appendReader.ReadToEnd ());
        }
        foreach (var item in appendData) {
            inputData.TryAdd (item.Key.ToString (), item.Value);
        }
        using (TextWriter outputWriter = new StreamWriter ("outputData.json")) {
            outputWriter.Write (JsonConvert.SerializeObject (inputData));
        }
    }
}

}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接