为什么需要新的JSON API?

JSON.NET 大家都用过,老版本的ASP.NET Core也依赖于JSON.NET。

然而这个依赖就会引起一些版本问题:例如ASP.NET Core某个版本需要使用JSON.NET v10,而另一个库需要使用JSON.NET v11;或者JSON.NET 出现了一个新版本,而ASP.NET Core还不能支持这个版本,而您却想使用该版本。

System.Text.Json

随着NET Core 3.0的出现,出现了System.Text.Json命名空间和它下面一些用于处理JSON的类。

特点

这个内置JSON API具有与生俱来的高性能、地分配的特点:

JSON.NET 使用.NET 里面的字符串作为基本数据类型,其实也就是UTF16,而.NET Core中新的JSON API直接使用数据原始的UTF8格式。

新的JSON API基于Span<byte>这个数据类型来进行操作JSON数据,从而具有低分配的特点,这就可以极大的改善吞吐量和内存使用情况。

但是新的JSON API的特性还不那么丰富,有一些JSON.NET具有的特性都还不支持。

例子

随便找了一个JSON示例文件:

针对这个文件,需要修改一下它的属性:

Utf8JsonReader

先使用 Utf8JsonReader 来读取JSON文件。

Utf8JsonReader 并不会读取文件或者stream,它会读取Span数据类型。

直接上代码:

Main方法里面,我们使用File.ReadAllBytes从sample.json文件读取数格式为byte[],然后通过AsSpan这个扩展方法将其转化为Span<byte>数据类型,然后把它传递到 Utf8JsonReader 的构造函数来创建一个JSON的reader。

接下来使用while循环对JSON数据的每个Token进行读取,每次执行Read()方法时,reader就会移动到JSON数据里面的下一个Token那里。

Token分成几种类型,GetTokenInfo方法就是判断一下Token的类型,并返回一些描述性信息,这里面应该是包含了所有的类型。这里面使用到了C# 8 的 switch 表达式。

运行程序

结果如下:

可以看到sample.json文件里面的每个Token都被正确的显示了。

JsonDocument类

JsonDocument是基于Utf8JsonReader 构建的。JsonDocument 可分析 JSON 数据并生成只读文档对象模型 (DOM),可对模型进行查询,以支持随机访问和枚举。使用 JsonDocument 分析常规 JSON 有效负载并访问其所有成员比使用 Json.NET 快 2-3 倍,且为合理大小(即 < 1 MB)的数据所分配的量非常少。

JsonDocument可以处理Span,也可以处理Stream。

例子:

这里我通过File.OpenRead把json文件转化为stream。然后使用JsonDocument.Parse方法把stream解析成JSON文档对象模型。

注意,这里我使用了C# 8的using var语法,这个以后再说。

下面我们开始从这个JSON文档对象模型的根节点开始遍历,也就是RootElement:

然后通过root这个JsonElement类型的对象的GetProperty方法来获得相应的属性,而且这个方法可以连串使用:

最后一行使用GetString方法来获得该属性的字符串值。

然后我们可以写一个递归调用的方法来遍历整个模型的每个属性:

这个方法接受JsonElement类型的对象,然后对该元素的属性进行循环。

如果当前属性是另一个对象,那么就继续递归调用这个方法;

否则就输出原始的文本。

最后调用该方法:

输出结果为:

与json文件的内容匹配。

Utf8JsonWriter类

下面研究一下如何写入json文件。这里需要使用Utf8JsonWriter类。

直接看代码:

这个类需要传递的参数类型是Stream或者Buffer,也就是向Stream或Buffer里面写入数据。

那么就提供一个buffer:

下面单独写一个方法,来生成json数据:

参数类型是Utf8JsonWriter。通过智能提示可以看到它提供了很多用于写入不同类型数据的方法。

写JSON对象

现在我想写一个json对象,那么就从WriteStartObject()开始,然后以WriteEndObject()结束:

这样的话,实际上我已经拥有了一个合法的json文档。

写属性和值

可以分开写属性和值:

也可以同时把属性和值写出来:

显示JSON数据

我先写这些内容,然后在Main方法里面调用一下:

首先需要告诉writer把它的内容flush给buffer,使用这个buffer我们可以获得writer的输出,这样的话就会得到一个byte数组,然后把这个byte数组转化为字符串,这样就可以在控制台显示它了:

运行一下看看效果:

没啥太大的问题,就是格式不好看。

对输出进行格式化

.NET Core提供了一个JsonWriterOptions类,它可以对Writer进行一些设置。

这里对输出进行了缩进,最后把这个options传递给Utf8JsonWriter的构造函数即可。

再次运行:

现在好看多了。

JsonSerializer

前面几节的内容可能稍微有点底层,我们大部分时候可能只需要对C#的类进行串行化或者将JSON数据反串行化成C#类,在.NET Core 3.0里面,我们可以使用JsonSerializer这个类来做这些事情。

例子:

还是使用之前用到的json数据:

然后我们需要建建立两个类,对应这个文件:

反串行化

可以使用JsonSerializer类的Deserialize()方法对json数据反串行化。这个方法支持三种类型的输入参数,分别是:

  • JSON数据的字符串

  • Utf8JsonReader

  • ReadOnlySpan<byte>,它里面包含JSON数据

为了简单一点,我直接把json文件读取成字符串,然后传给Deserialize方法:

然后我试图打印出反串行化之后的一些属性数据。但是这不会成功。因为JSON文件里面数据的大小写命名规范使用的是camel casing(简单理解为首字母是小写的),而默认情况下Deserializer会寻找Pascal casing这种规范(简单理解为每个单词的首字母都是大写的)的属性名。

格式化

为解决这个问题,就需要使用JsonSerializerOptions类:

建立该类的一个实例,设置PropertyNamingPolicy为CamelCase,然后把这个实例传递给Deserialize方法的第二个参数。

运行看结果:

这次就没有问题了。

串行化

JsonSerializer也支持串行化,也就是把C#数据转化为JSON数据:

这里使用了相同的options。

运行结果:

如果想让输出结果更好看一些,可以在JsonSerializerOptions里面进行相应的设置:

这次输出结果为:

总结

总结一下.NET Core 3.0新的JSON API:

  • Utf8JsonReader - 读操作,快速,低级

  • Utf8JsonWriter - 写操作,快速,低级

  • JsonDocument - 基于DOM,快速

  • JsonSeriliazer - 串行化/反串行化,快速

另外 JSON.NET 仍然被支持。

.NET Core 3.0 里新的JSON API的更多相关文章

  1. HDD成都站:HMS Core 6.0带来新可能 多元服务驱动产品商业成功

    9月10日,由华为开发者联盟主办的HDD(Huawei Developer Day)于成都举行.活动中,华为HMS Core各领域专家重点解读了HMS Core 6.0为开发者带来的多项全新能力,及生 ...

  2. EF Core 6.0的新计划

    今天,我们很兴奋地与你分享Entity Framework Core 6.0的计划. 这个计划汇集了许多人的意见,并概述了我们打算在哪里以及如何优化实体框架(EF Core) 6.0版本.这个计划并不 ...

  3. 在 .NET Core 3.0 中支持 Newtonsoft.Json 的使用

    .NET Core 3.0 已经使用了一整套内置的 Josn 序列化/反序列化方案,而且看上去效率还不错.但对于某些项目必须使用到 Newtonsoft.Json 的时候,就会抛出如下异常: Syst ...

  4. 用ASP.NET Core 2.0 建立规范的 REST API

    什么是REST REST 是 Representational State Transfer 的缩写. 它是一种架构的风格, 这种风格基于一套预定义的规则, 这些规则描述了网络资源是如何定义和寻址的. ...

  5. 用ASP.NET Core 2.0 建立规范的 REST API -- 预备知识 (2) + 准备项目

    上一部分预备知识在这 http://www.cnblogs.com/cgzl/p/9010978.html 如果您对ASP.NET Core很了解的话,可以不看本文, 本文基本都是官方文档的内容. A ...

  6. 用ASP.NET Core 2.0 建立规范的 REST API -- 预备知识

    什么是REST REST 是 Representational State Transfer 的缩写. 它是一种架构的风格, 这种风格基于一套预定义的规则, 这些规则描述了网络资源是如何定义和寻址的. ...

  7. 用ASP.NET Core 2.0 建立规范的 REST API -- 预备知识1

    什么是REST REST 是 Representational State Transfer 的缩写. 它是一种架构的风格, 这种风格基于一套预定义的规则, 这些规则描述了网络资源是如何定义和寻址的. ...

  8. Asp.Net Core 3.0 学习3、Web Api 文件上传 Ajax请求以及跨域问题

    1.创建Api项目 我用的是VS2019 Core3.1 .打开Vs2019 创建Asp.Net Core Web应用程序命名CoreWebApi 创建选择API 在Controller文件夹下面添加 ...

  9. 用ASP.NET Core 2.0 建立规范的 REST API -- DELETE, UPDATE, PATCH 和 Log

    本文所需的一些预备知识可以看这里: http://www.cnblogs.com/cgzl/p/9010978.html 和 http://www.cnblogs.com/cgzl/p/9019314 ...

随机推荐

  1. springboot之全局处理异常封装

    springboot之全局处理异常封装 简介 在项目中经常出现系统异常的情况,比如NullPointerException等等.如果默认未处理的情况下,springboot会响应默认的错误提示,这样对 ...

  2. linux安装couchbase

    一.卸载 查看已安装的版本 rpm -qa|grep couchbase 卸载已安装的版本 rpm -e xxxx 二.安装 安装couchbase rpm -i xxxx.rpm 浏览器中访问809 ...

  3. 安全性测试:OWASP ZAP 2.8 使用指南(三):ZAP代理设置

    ZAP本地代理设置 如前文所言,ZAP的工作机制,是通过“中间代理”的形式实现. ZAP的代理设置可以从菜单中的:工具 - 选项 - Local Proxies加载. 在这里可以设置ZAP用来接受接入 ...

  4. 【PyTorch】Tricks 集锦

    声明:本文大部分内容是从知乎.博客等知识分享站点摘录而来,以方便查阅学习.具体摘录地址已在文章底部引用部分给出. 1. 查看模型每层输出详情 from torchsummary import summ ...

  5. [LeetCode]Power of N

    题目:Power of Two Given an integer, write a function to determine if it is a power of two. 题意:判断一个数是否是 ...

  6. 让tomcat使用指定JDK

    一,前言 我们都知道,tomcat启动前需要配置JDK环境变量,如果没有配置JDK的环境变量,那么tomcat启动的时候就会报错,也就是无法启动. 但是在我们的工作或者学习过程中,有的时候会出现tom ...

  7. 通过python代码对域名ssl证书进行监控

    根据公司要求,要求用zabbix对域名的ssl证书进行到期监控 直接上代码 #!/usr/bin/env python3 from urllib3.contrib import pyopenssl f ...

  8. Spring Data JPA 梳理 - JPA与“Spring、Spring Data JPA”的关系

    JPA其实也就是java实体对象和关系型数据库建立起映射关系,通过面向对象编程的思想操作关系型数据库的规范. Spring 框架对 JPA 提供的支持主要体现在如下几个方面: 首先,它使得 JPA 配 ...

  9. 【PCIE-1】---Pcie基本概念普及(扫盲篇--巨适合新手)

    PCIE由早期得PCI扩展衍生而来并且对兼容PCI,两者得主要区别在于并行到串行得切换,且速率更快.目前主板上越来越多得设备都挂载到PCI总线下面,甚至部分硬盘也会挂载PCI总线下面,可见PCIE得应 ...

  10. windows安装Mycat并测试

    1.下载系统安装包 选择相应的版本进行下载,地址:http://dl.mycat.io/ .Mycat数据库分库分表中间件介绍 http://www.mycat.io/ 2.安装 安装mycat前需要 ...