You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用JSON.net合并JSON时空对象未覆盖原对象的问题

问题:Json.NET合并时空对象无法覆盖原对象

我用Json.NET写了一段合并完整JSON和部分JSON的代码,遇到空对象场景时不符合预期:

代码示例

string jsonOrigen = @"
 {
     'business': {
         'tradingaccount': [
             '60325f59-6bef-418a-69a1-08db40bce9af',
             '054ae632-9b82-4644-6e8c-08db45721efd'
         ],
         'campaign': [
             'cf308053-3118-4e92-7bb7-08db73cba4df',
             '5ad21da9-337a-4afc-7bb8-08db73cba4df'
         ],
         'service': [
             'ab14b586-38d8-41a2-01d4-08db86a59448',
             'adac9392-d602-4874-01d5-08db86a59448'
         ]
     }
 }";

string jsonParcial = @"{ 'business': {} }";

JObject tokenOrigen = JObject.Parse(jsonOrigen);
JObject tokenParcial = JObject.Parse(jsonParcial);

tokenOrigen.Merge(tokenParcial, new JsonMergeSettings
{
    MergeNullValueHandling = MergeNullValueHandling.Merge
});

string res = tokenOrigen.ToString(Formatting.Indented);

预期输出

"business": {}

实际输出

{
  "business": {
    "tradingaccount": [
      "60325f59-6bef-418a-69a1-08db40bce9af",
      "054ae632-9b82-4644-6e8c-08db45721efd"
    ],
    "campaign": [
      "cf308053-3118-4e92-7bb7-08db73cba4df",
      "5ad21da9-337a-4afc-7bb8-08db73cba4df"
    ],
    "service": [
      "ab14b586-38d8-41a2-01d4-08db86a59448",
      "adac9392-d602-4874-01d5-08db86a59448"
    ]
  }
}

原因分析

Json.NET的Merge方法默认逻辑是合并对象的属性,空对象{}没有任何属性,所以不会对原对象的属性做修改。MergeNullValueHandling.Merge仅针对null值生效,空对象不属于null,因此无法触发覆盖行为。

解决方案

方法1:手动检查并替换空对象

遍历部分JSON的属性,若属性值是空JObject,直接替换原对象的对应属性,而不是用Merge:

string jsonOrigen = @"
 {
     'business': {
         'tradingaccount': [
             '60325f59-6bef-418a-69a1-08db40bce9af',
             '054ae632-9b82-4644-6e8c-08db45721efd'
         ],
         'campaign': [
             'cf308053-3118-4e92-7bb7-08db73cba4df',
             '5ad21da9-337a-4afc-7bb8-08db73cba4df'
         ],
         'service': [
             'ab14b586-38d8-41a2-01d4-08db86a59448',
             'adac9392-d602-4874-01d5-08db86a59448'
         ]
     }
 }";

string jsonParcial = @"{ 'business': {} }";

JObject tokenOrigen = JObject.Parse(jsonOrigen);
JObject tokenParcial = JObject.Parse(jsonParcial);

// 遍历部分JSON的属性,处理空对象覆盖
foreach (var prop in tokenParcial.Properties())
{
    if (prop.Value is JObject jObj && !jObj.HasValues)
    {
        // 空对象,直接替换原对象的属性
        tokenOrigen[prop.Name] = prop.Value;
    }
    else
    {
        // 非空对象,正常合并
        tokenOrigen.Merge(prop.Value, new JsonMergeSettings
        {
            MergeNullValueHandling = MergeNullValueHandling.Merge
        });
    }
}

string res = tokenOrigen.ToString(Formatting.Indented);

方法2:自定义合并逻辑(支持嵌套场景)

如果需要处理嵌套的空对象覆盖,可以写递归方法实现:

public static void MergeWithEmptyObjectOverwrite(JObject target, JObject source, JsonMergeSettings settings)
{
    foreach (var prop in source.Properties())
    {
        if (prop.Value is JObject sourceObj && !sourceObj.HasValues)
        {
            target[prop.Name] = sourceObj;
        }
        else if (prop.Value is JObject sourceNested && target[prop.Name] is JObject targetNested)
        {
            // 嵌套对象,递归处理
            MergeWithEmptyObjectOverwrite(targetNested, sourceNested, settings);
        }
        else
        {
            // 其他类型,正常合并
            target.Merge(prop.Value, settings);
        }
    }
}

// 使用方式
MergeWithEmptyObjectOverwrite(tokenOrigen, tokenParcial, new JsonMergeSettings
{
    MergeNullValueHandling = MergeNullValueHandling.Merge
});

运行修改后的代码,就能得到预期的"business": {}结果。

内容的提问来源于stack exchange,提问作者Kiquenet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 15:27:48