【问题标题】:how to do a JSON diff/patch between 2 big nested json from .net backend to js frontend?如何在从 .net 后端到 js 前端的 2 个大嵌套 json 之间进行 JSON diff/patch?
【发布时间】:2020-11-24 10:29:24
【问题描述】:

我有一个非常大的 json,每秒有一个非常小的变化。

我使用 asp.net 核心 3.1 和信号器核心。并且客户端使用的是运行纯 js 和 jquery 的浏览器。

现在对于每次更改,我都会再次发送所有 json。我知道这不是一个好方法。

我想要做的只是将更改发送到客户端,然后将更改修补到 javascript 中的主 JSON。

通过谷歌搜索,我了解到它是一个 JSON diff/patch 或 diff/Merge 操作,但我没有找到任何关于如何实现它的信息。

那么,我怎样才能在信号器中实现 diff/pach 操作?

J_m 和 j_m_lit 可能有 100 个键。

数据结构

[
   {
      "id":0,
      "stdid":3808003,
      "lid":10533,
      .
      .
      (40 root keys)
      .
      .
      "J_ps":null,
      "J_ms":null,
      "J_m":{
         "SA_H2 0":{
            "c":"SA_H2",
            "a":"0",
            "b":0,
            "r":"0",
            "w":0,
            "en":"2nd",
            "o":{
               "2:0":{
                  "c":"2:0",
                  "v":1.3,
                  "pv":0.0,
                  "b":0
               },
               "Tie":{
                  "c":"Tie",
                  "v":3.2,
                  "pv":0.0,
                  "b":0
               }
            }
         },....
       
      },
      "J_m_Lit":{
         "OE 0":{
            "c":"OE",
            "a":"0",
            "b":0,
            "r":"0",
            "w":0,
            "en":"Total ",
            "o":{
               "xxx":{
                  "c":"Odd",
                  "v":1.833,
                  "pv":0.0,
                  "b":0
               },
               "zzz":{
                  "c":"Even",
                  "v":1.833,
                  "pv":0.0,
                  "b":0
               }
            }
         },  ....

      },
    
      "J_fre":{
         "tq":[
            0,
            1
         ],
         "m1":[
            23,
            17
         ]
      },
     
   }
]

【问题讨论】:

  • "通过谷歌搜索,我了解到它是一个 JSON diff/patch 或 diff/Merge 操作" 不,这是一个 data diff/merge 问题。用于将数据从服务器传输到客户端的序列化格式无关紧要。为了解决您的问题,您能否提供一些有关数据结构和更改的数量/结构的信息?就像这只是一个相当简单/平面模型的巨大列表,其中偶尔会发生一些变化?或者它是一个高度嵌套的模型,其中可能存在需要传输的任何级别的更改。
  • 实际上它是一个最大深度为 4 的大对象数组。它不是平坦的,变化可能在任何深度上。我不能给你确切的数据,但我会用数据结构的想法编辑问题。
  • 最精确但也是最麻烦的方法是区分值,然后将{id:0, "J_m.SA_H2 0.a":1,"J_m.SA_H2 0.b":2, "J_m_Lit.OE 0.o.xxx": {...}} 之类的内容发送到前端。根据更改的范围,您还可以使用整个块甚至整行;仍然比发送整个行列表更好。在前端,通过 id 获取条目然后for(let key in objectWithChanges){ const path = key.split("."), value = objectWithChanges[key]; ... } 遍历路径并设置值(无论是原始值还是对象)应该是微不足道的

标签: javascript json signalr asp.net-core-3.1 json-patch


【解决方案1】:

是的,我认为你在正确的轨道上。

JSON-Patch (RFC6902) 的核心是试图解决您在这里面临的问题:部分更新。 JSON Patch 提供了一个原子更新请求,它使用一系列“添加”、“删除”、“替换”、“移动”和“复制”操作来修补您的 JSON。 To quote JSON Patch RFC 的作者之一,Mark Nottingham (IETF):

这有很多优点。由于它是通用格式,因此您可以 编写一次服务器端和客户端代码,并在多个数字之间共享 的应用程序。您可以进行一次 QA,并确保您做对了。 此外,您的 API 将变得不那么复杂,因为它具有更少的 URI 约定,带来更大的灵活性并使其更容易 新开发人员的方法。使用这种方法也会使缓存 操作更正确;因为对资源的修改会 “旅行”通过它的 URL,而不是其他一些,存储的权利 响应将失效。

ASP.NET Core 提供 JSON-Patch 支持。 JSON Patch 可以通过从 Package Manager 控制台安装 Microsoft JSON Patch 库 (Nuget) 来添加:

Install-Package Microsoft.AspNetCore.JsonPatch

然后您使用JsonPatchDocument 类及其方法(如ApplyToAddCopyMoveRemoveReplace)应用补丁。

在 ASP.NET Core Web API 上下文中,我们还可以使用 Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet 包。

然后使用 PUT 和 PATCH 方法通过 JSON Patch 操作更新现有资源。

This MSDN 文章有一些很好的解释和一个示例项目。


在 JavaScript/Node.js 项目中,您还可以从更大的 JS 实现列表中进行选择,特别是 fast-json-patch

资源:


旁注:另一个选项是JSON Merge Patch (RFC7396),它也可以用于发送部分更新,但它更像是一个实际的差异/补丁,它只包含更改而不是使用变异操作。在这方面,JSON Merge Patch 比 JSON Patch 更简单但更受限制,例如您不能将键设置为 null(因为 null 表示删除),合并仅适用于对象 {..},数组 [..] 只能作为一个整体替换,并且合并永远不会失败,可能会导致副作用,因此不是事务性的。这使得 Merge Patch(过度)简单化并且对于某些实际应用程序不切实际。还有更多类似 JSON-Diffpatch 等的相关项目采用了类似的方法。可以说,JSON-Patch 更灵活,但两者都有优点和缺点。

【讨论】:

    猜你喜欢
    • 2014-02-09
    • 2018-10-02
    • 1970-01-01
    • 2019-05-25
    • 1970-01-01
    • 2021-10-08
    • 1970-01-01
    • 1970-01-01
    • 2020-11-01
    相关资源
    最近更新 更多