【ASP.NET Core】JSON Patch 使用简述

JSON Patch 是啥玩意儿?不知道,直接翻译吧,就叫它“Json 补丁”吧。干吗用的呢?当然是用来修改 JSON 文档的了。那咋修改呢?比较常见有四大操作:AMRR。

咋解释呢?

A—— Add;

M—— Move;

R—— Replace;

R—— Remove。

Add 就是向 JSON 对象中添加一对 key - value,或者向 Json Array 中加个元素。

Move 就是把某个节点从一个地方移到另一个地方。

Replace 就是替换,比如把 city 的值从“广州”改为“珠海”。

Remove 就是删除 JSON 对象中的某对 key - value,或者从 Json Array 中删除一个元素。

除了上述四大美女外,还有 copy,就是把某个节点复制到另一个地方;test 这个嘛,在修改 JSON 文档之前验证某个值,如果值正确了就进行更新,如果值不对就“呵呵“,比如,可以 test 一下 age 属性是否为 25,如果是就更新 SON 文档,如果不是就算了吧。

这个 JSON Patch 也不是很复杂,你可以参考主页上的说明,主页地址:http://jsonpatch.com/

 

这个 JSON Patch 有什么用呢?有用得很!尤其是现在很多数据都是通过网络来传输的,而且许多数据也喜欢用 JSON 格式(貌似是比 XML 简单一些)。如果 JSON 文档比较长,客户端获取了数据后,然后可能会对数据进行更新,然后更新时又把整个 JSON 文档提交回服务器。虽然这一来一回,所产生的流量远不如你打《王者农药》所产生的流量,但是,如果传输频繁,这个流量消耗也是不小的,毕竟各大运营商是增不降费的。按照现在各种破 App 内含数不胜数的虚假广告和一些无用的图片信息,刷几条微博就刷掉 5-6 M 的流量了。

所以说,尽量减少传输量是很有必要的。JSON Patch 不必把整个 JSON 文档都提交回服务器,而仅告诉服务器你要更新哪个地方就好了。比如

[
   { "op" : "add", "path" : "/age", "value" : "150" },
   { "op" : "replace", "path" : "/name", "value" : "老鬼" }
]

注意,JSON Patch 本质上也是一个 JSON 文档。在写的时候,要记得最外面有一层中括号,为啥?你都看到了,是个数组。因为你可以同时把多个操作组合在一起提交。就像上面的,add 和 replace 操作就一起提交了。

 

当然了,老周本文重点是介绍如何在 ASP.NET Core 中使用 JSON Patch 的,所以,下面咱们切入正题,不说 F 话了。

ASP.NET Core 的 API 自身也有与 JSON Patch 相关的实现,所以,用起来还是挺省心的。这些 API 都分布在 Microsoft.AspNetCore.JsonPatch.* 命名空间中。

相当核心的一个类就是 JsonPatchDocument<TModel>,TModel 是指你要用来生成 JSON 文档的模型类。当客户端提交 JSON Patch 上来后,会自动包含在该对象上,然后你只要调用一下 AppliyTo 方法就可以对模型对象进行更新了。

非常简单的,下面老周就给你演示一下。这里我用的 Web API ,因为这一情形是最为常用的。模型对象是一个字典实例—— IDictionary<string, object>,之所以用字典,是因为字典比较好添加属性。

添加一个 API 控制器类,然后初始化一个字典实例。

    [Route("api/[controller]")]
    public class DemoController : Controller
    {
        IDictionary<string, object> dic = new Dictionary<string, object>
        {
            ["name"] = "非洲黑鹿",
            ["age"] = 35,
            ["phone"] = "19929939900"
        };
    }

 

为了可以获取数据,可以定义一个 HTTP-GET 方法访问的方法,并将字典以 JSON 文档返回。

        [HttpGet("pick")]
        public IActionResult PickData()
        {
            return Json(dic);
        }

 

下面来重点了,为了能够使用 JSON Patch 来更新字典对象,还要弄一个以 HTTP-POST 方法提交的方法。

        [HttpPost("set")]
        public IActionResult SetData([FromBody]JsonPatchDocument<IDictionary<string,object>> body)
        {
            body.ApplyTo(dic);
            return Json(dic);
        }

请严重注意:

1、方法参数的类型是 JsonPatchDocument<TModel>,这样服务器收到客户端提交的 JSON Patch 文档后会自动创建 JsonPatchDocument 实例并传递给 body 参数。

2、在参数上要应用 FromBodyAttribute (特性),因为你得告诉运行时,客户端 POST 上来的整个数据正文将用于生成 JSON Patch 文档。

3、更新字典实例很简单,直接调用 JSON Patch 文档的 ApplyTo 方法就完事了。

 

好了,就是这么简单,这个演示的例子就完工了。不过得打开 Program.cs 文件,配置一下 Host。

 

        public static void Main(string[] args)
        {
            WebHostBuilder bd = new WebHostBuilder();
            bd.UseContentRoot(Directory.GetCurrentDirectory())
                .UseStartup<Startup>()
                .UseUrls("http://*:6000")
                .UseKestrel();
            var host = bd.Build();
            host.Run();
        }

 

http://*:6000 表示应用程序的 URL 在 6000 端口上侦听连接,* 表示绑定给本机的任意主机名。比如 localhost。

 

在 Startup 类中,还要配置 MVC 的内容,Web API 其实也是 MVC 的一种,只是它不返回 HTML 。

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
        }

        public void Configure(IApplicationBuilder app)
        {
            app.UseMvc();
        }

由于刚才在 DemoController 控制器中已经用了路由特性指定了路由规则,那么这里就不用再配置全局路由规则了。

   [Route("api/[controller]")]

 

好,现在我们来测试一下。测试 API 可以用 Postman 大叔,因为它比较牛。

首先,输入 URL http://localhost:6000/api/demo/pick,方式为 GET。

然后返回以下数据。

 

现在,我们把里面的 name 属性改为“巴西龟”。输入 URL  http://localhost:6000/api/demo/set,提交方式为 POST。

选择 “body” ,格式选 raw,Content Type 选 JSON ( application / json )。

然后输入以下 JSON 。

[
 { "op" : "replace",
   "path" : "/name", 
   "value" : "巴西龟" 
 }
]

提交之后,得到更新后的字典数据。

 

我们还可以进行多个操作,除了修改 name 的值,还可以考虑添加一个项。

[
 { "op" : "replace",
   "path" : "/name", 
   "value" : "巴西龟" 
 },
 {
   "op" : "add",
   "path" : "/email",
   "value" : "small-pig@163.com"
 }
]

向字典添加一个 email 字段。

发送请求后,返回字典数据的最新内容。

 

好了,简单的演示就结束了。

最后,老周还要强调一点,就是如果你的 JSON Patch 文档的 TModel 是一个类,由于 .NET 是面向对象的,你不能随便向一个类添加属性,因此,add 操作对于类是不可行的,但你可以进行 replace 操作。

 

=============================

前两天,也就是上个星期六,由于张老鬼找老周有点事情研究,所以【闲聊 ASP.NET Core】的直播暂停一次。这个星期可以补上,周六周日都行,到时候老周会在微博上发一下时间,因为这个周末,女朋友所在的公司组织全体员工去长途旅游,所以这个周末老周就可以自由了,爱干吗就干吗。

我们俩都是穷人家的孩子,双方都没有车,距离又有点远,每次见面都要滴滴打车,所以一个月也只能见两三次面。这个五月她那边比较忙,只见了一次面。没办法,想天天去浪是不可能的了。这就是咱们平头百姓的生活。

 

posted @ 2018-05-14 11:46  东邪独孤  阅读(...)  评论(...编辑  收藏