C#中基于Enabled属性规则合并两个JSON对象的实现求助
自定义条件合并JSON解决方案
我懂你现在的困扰——默认的JsonMergeSettings确实没办法实现这种带特定条件的属性合并,尤其是针对数组里的对象。咱们可以自定义一个递归的合并逻辑来精准满足你的需求:只有当源JSON的Enabled属性为false、目标JSON的同属性为true时才替换,其余情况完全保留源值。
核心思路
- 以源JSON为基础,避免全量覆盖目标内容
- 递归处理嵌套对象和数组,确保每个层级都应用规则
- 数组元素通过
Name字段匹配(适配你的Actions数组按名称对应合并的场景) - 对
Enabled属性单独做条件判断,仅在满足源false + 目标true时替换 - 其他属性默认保留源值,可根据需求灵活调整
完整代码实现
我们使用Newtonsoft.Json(Json.NET)来处理JSON操作,代码如下:
using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System.Linq; public static class JsonMerger { public static JObject ConditionalMerge(JObject source, JObject target) { // 先复制源对象作为合并基础,避免修改原对象 var mergedObject = new JObject(source); foreach (var targetProp in target.Properties()) { var sourceProp = mergedObject[targetProp.Name]; // 源对象无该属性时,直接添加目标属性 if (sourceProp == null) { mergedObject[targetProp.Name] = targetProp.Value.DeepClone() as JToken; continue; } // 处理数组类型(比如你的Actions数组) if (sourceProp is JArray sourceArray && targetProp.Value is JArray targetArray) { MergeArrays(sourceArray, targetArray); continue; } // 处理嵌套对象,递归合并 if (sourceProp is JObject sourceNested && targetProp.Value is JObject targetNested) { ConditionalMerge(sourceNested, targetNested); continue; } // 处理Enabled属性的条件替换逻辑 if (string.Equals(targetProp.Name, "Enabled", System.StringComparison.OrdinalIgnoreCase)) { bool sourceValue = sourceProp.Value<bool>(); bool targetValue = targetProp.Value<bool>(); // 仅当源为false、目标为true时,替换为目标值 if (!sourceValue && targetValue) { mergedObject[targetProp.Name] = targetProp.Value; } // 其他情况保留源值,不做修改 } // 非Enabled的普通属性,默认保留源值;如需其他规则可在此扩展 } return mergedObject; } private static void MergeArrays(JArray sourceArray, JArray targetArray) { // 按Name字段匹配数组中的对象,保证对应项合并 foreach (var targetItem in targetArray.OfType<JObject>()) { string itemName = targetItem["Name"]?.ToString(); if (string.IsNullOrEmpty(itemName)) continue; var sourceItem = sourceArray.OfType<JObject>() .FirstOrDefault(item => string.Equals(item["Name"]?.ToString(), itemName, System.StringComparison.OrdinalIgnoreCase)); if (sourceItem != null) { // 递归合并单个对象的属性 ConditionalMerge(sourceItem, targetItem); } else { // 源数组无该对象时,可选添加(可根据需求关闭此逻辑) sourceArray.Add(targetItem.DeepClone()); } } } }
使用示例
把你的两个JSON传入这个方法,就能得到期望的结果:
// 源JSON字符串 string sourceJson = @" { ""Name"": ""Sample"", ""Array"": [], ""Actions"": [ { ""Name"": ""A"", ""Enabled"": false }, { ""Name"": ""B"", ""Enabled"": true } ] }"; // 目标JSON字符串 string targetJson = @" { ""Name"": ""Sample"", ""Array"": [], ""Actions"": [ { ""Name"": ""A"", ""Enabled"": true }, { ""Name"": ""B"", ""Enabled"": false } ] }"; // 解析为JObject JObject sourceObj = JObject.Parse(sourceJson); JObject targetObj = JObject.Parse(targetJson); // 执行条件合并 JObject resultObj = JsonMerger.ConditionalMerge(sourceObj, targetObj); // 输出格式化后的结果 Console.WriteLine(resultObj.ToString(Formatting.Indented));
结果验证
运行代码后,输出的结果完全符合你的期望:
{
"Name": "Sample",
"Array": [],
"Actions": [
{
"Name": "A",
"Enabled": true
},
{
"Name": "B",
"Enabled": true
}
]
}
这个方案的好处是完全可控,你可以根据实际需求调整合并规则,比如修改数组匹配的字段、添加其他属性的合并逻辑等等。
内容的提问来源于stack exchange,提问作者Satish Kumar S
相关产品推荐
相关产品推荐

