如何将JsonDiffPatchDotNet生成的操作应用到Newtonsoft JObject上
客户端应用JsonDiffPatchDotNet生成的Delta操作方案
JsonDiffPatchDotNet的JsonDeltaFormatter输出的Operation列表完全遵循RFC 6902 JSON Patch标准,你可以直接用Newtonsoft.Json内置的补丁能力完成应用,不需要自己从头实现全量逻辑。
推荐方案:使用Newtonsoft.Json自带的JsonPatch功能
你只需要在客户端项目引用Newtonsoft.Json包即可,无需额外引入其他依赖,实现步骤如下:
- 服务端序列化
opsArray时不需要做额外格式转换,默认输出的JSON结构已经完全符合JSON Patch规范 - 客户端收到序列化后的补丁字符串后,反序列化为
JsonPatchDocument对象 - 调用内置的
ApplyTo方法即可将差异直接应用到目标JObject上
客户端代码示例
using Newtonsoft.Json; using Newtonsoft.Json.JsonPatch; using Newtonsoft.Json.Linq; // 服务端传输过来的opsArray序列化字符串 string patchJson = "你收到的差异字符串"; // 反序列化为标准JSON Patch文档 JsonPatchDocument patchDocument = JsonConvert.DeserializeObject<JsonPatchDocument>(patchJson); // 客户端本地要更新的原JObject对象 JObject localObject = _clientInstance; // 直接应用补丁完成更新 patchDocument.ApplyTo(localObject);
轻量实现方案:手动实现补丁逻辑
如果你的运行环境无法引入Newtonsoft.Json的Patch相关命名空间,可以手动实现核心操作逻辑,JSON Patch的操作规则非常简单,核心逻辑如下:
public static void ApplyPatch(JObject target, JArray patchOperations) { foreach (JObject op in patchOperations) { string opType = op.Value<string>("op"); string path = op.Value<string>("path").TrimStart('/').Replace('/', '.'); JToken value = op.GetValue("value"); string fromPath = op.Value<string>("from")?.TrimStart('/').Replace('/', '.'); switch (opType) { case "replace": JToken replaceTarget = target.SelectToken(path); replaceTarget?.Replace(value); break; case "remove": JToken removeTarget = target.SelectToken(path); removeTarget?.Remove(); break; case "add": int lastDotIndex = path.LastIndexOf('.'); string parentPath = path.Substring(0, lastDotIndex); string nodeName = path.Substring(lastDotIndex + 1); JToken parent = target.SelectToken(parentPath); if (parent is JObject parentObj) { parentObj[nodeName] = value; } else if (parent is JArray parentArr && int.TryParse(nodeName, out int arrIndex)) { parentArr.Insert(arrIndex, value); } break; // 按需补充copy、move、test等操作的实现逻辑 } } } // 调用示例 ApplyPatch(_clientInstance, receivedOpsArray);
注意:如果服务端生成补丁时开启了数组位置优化、移动检测等高级配置,建议优先使用官方
JsonPatchDocument实现,避免手动实现出现边界情况兼容问题。
内容的提问来源于stack exchange,提问作者besplash
相关产品推荐
相关产品推荐

