【C# 序列化】Json 数据交换格式

JSON数据交换格式

 

 

 Json简介

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。人类很容易读写。机器很容易解析和生成。它基于 JavaScript 编程语言标准 ECMA-262 第 3 版的子集 - 1999 年 12 月。JSON是一种完全独立于语言的文本格式,但使用C系列语言程序员熟悉的约定,包括C,C++,C#,Java,JavaScript,Perl,Python等。这些属性使 JSON 成为理想的数据交换语言。最新的Json 标准 RFC 8259,C#采用改标准。

这些是通用的数据结构。几乎所有现代编程语言都以这种或那种形式支持它们。与编程语言可互换的数据格式也基于这些结构是有道理的。

官方规范与其他规范

即使在最好的情况下,规范的实现也不可避免地存在一些轻微的、非故意的偏差。除此之外,JSON解析器还面临一些额外的挑战:即使在官方的JSON RFC中,也存在关于某些主题的开放式指导,例如如何处理重复的键和表示数字等。虽然这些指导后面有关于互操作性的免责声明,但大多数JSON解析器的用户并不了解这些注意事项。

造成解析器之间不一致的原因之一是存在多种不同的规范。

· IETF JSON RFC (8259及以前的版本):这是互联网工程任务组(IETF)的官方规范( System.Text.Json C# Json 默认采用)。

· ECMAScript标准:对JSON的更改是与RFC版本同步发布的,该标准参考了RFC关于JSON的指导。然而,JavaScript解释器提供的不合规范的便利性,如无引号字符串和注释,则激发了许多解析器的“创造”灵感。

· JSON5:这个超集规范通过明确地添加便利性特征(如注释、备选引号、无引号字符串、尾部逗号)来增强官方规范。

· HJSON:HJSON在思想上与JSON5类似,但在设计上则具有不同的选择。

· 还有更多..

JSON语法

JSON 建立在两个结构之上:

  • 名称/值对的集合。在各种语言中,这被实现为对象,记录,结构,字典,哈希表,键控列表或关联数组。
  • 值的有序列表。在大多数语言中,这被实现为数组、向量、列表或序列。

——JSON文本是一系列标记。这组标记包括六个结构字符、字符串、数字和三个文字名称。
——JSON文本是一个序列化的值。注意,以前的某些JSON规范将JSON文本限制为对象或数组。只生成调用JSON文本的对象或数组的实现将是可互操作的,因为所有实现都将接受这些作为符合JSON文本的实现。

1、六个结构字符:

      begin-array     = ws %x5B ws  ; [ left square bracket
      begin-object    = ws %x7B ws  ; { left curly bracket


      end-array       = ws %x5D ws  ; ] right square bracket
      end-object      = ws %x7D ws  ; } right curly bracket


      name-separator  = ws %x3A ws  ; : colon
      value-separator = ws %x2C ws  ; , comma

2、值

——JSON值必须是数字、字符串、对象、数组,或以下三个文字名称之一:
在这里插入图片描述
文字名称必须是小写。不允许使用其他文字名称。
在这里插入图片描述

3.对象

——对象结构表示为围绕零或多个名称/值对(或多个成员)的一对花括号。名称是字符串。在每个名称之后加上一个冒号,将名称与值分隔开来。一个逗号将值与接下来的名称分隔开来。对象中的名称应该是唯一的
在这里插入图片描述
——所有名称都唯一的对象是可互操作的,因为接收该对象的所有软件实现都会在【名称-值】映射上达成一致。当对象中的名称不是唯一的时,接收此类对象的软件的实现行为是不可预测的。许多实现只报告名称/值对。其他实现会报告错误或无法解析对象,而一些实现则会报告所有名称/值对,包括重复的名称/值对。
——JSON解析库对于它们是否使对象成员的排序对调用软件是可见的,已经观察到了不同的情况。其行为不依赖于成员排序的实现将是可互操作的,因为它们不会受到这些差异的影响。

4.数组

——数组结构表示为围绕零个或多个值(或多个元素)的方括号。元素用逗号分隔
在这里插入图片描述
——不要求数组中的值具有相同的类型。

5.数字

——数字的表示与大多数编程语言中使用的表示类似。一个数字用十进制数字以基数10表示。它包含一个整数分量,其前缀可以是可选减号,后面可以是分数部分和/或指数部分。不允许前导零。
——分数部分是小数点,后面跟着一个或多个数字。
——指数部分以大写或小写字母E开头,后面可以是正负号。E和可选符号后面跟着一个或多个数字。
——不允许使用【不能用下面的语法表示的】数值(如Infinity和NaN)。
在这里插入图片描述
在这里插入图片描述
——该规范允许【implementations】对所接受的数字的范围和精度设置限制。由于实现IEEE 754二进制64(双精度)数字[IEEE 754]的软件是普遍可用和广泛使用的,因此只要【implementations】的精度或范围不超过广泛使用的标准,就可以实现良好的互操作性,因为【implementations】将在预期的精度范围内近似于JSON数字。
——诸如1E400或3.14159265357932384626383279这样的JSON数字可能有潜在的互操作性问题,因为如果创建的软件使用这样的数字,该创建的软件会希望接收方软件在数值范围和精度方面比广泛可用的软件更大。
——请注意,当使用这种软件时,属于整数且在[-(253)+1,(253)-1]范围内的数字是可互操作的,因为实现将精确地商定它们的数值。

6.字符串

——字符串的表示类似于C系列编程语言中使用的约定。字符串以单引号开头和结尾。所有Unicode字符都可以放在引号中,但必须转义的字符除外:引号、反斜线分隔符\和控制字符(U+0000到U+001 F)。
——任何字符都可以转义。如果字符位于基本的多语言平面(从U+0000到U+FFFF),那么它可以表示为六个字符序列:反斜线分隔符\,后面跟着小写字母u,后面跟着四个十六进制数字,编码字符的代码点。十六进制字母A到F可以是大写字母,也可以是小写字母。因此,例如,只包含一个反向Solidus字符的字符串可以表示为“\u005C”。
——另外,也有一些流行字符的双字符序列转义表示形式。因此,例如,只包含一个反向Solidus字符的字符串可以更紧凑地表示为“\”。
——为了转义不属于基本多语言平面的扩展字符,该字符被表示为12个字符序列,编码UTF-16代理项对。因此,例如,只包含G clef字符(U+1D11E)的字符串可以表示为“\uD 834\uDD1E”。
在这里插入图片描述

  

7\字符串和字符问题

7.1.字符编码

——在不属于封闭生态系统的系统之间交换的JSON文本必须使用UTF-8[RFC 3629]编码。

——以前的JSON规范在传输JSON文本时不需要使用UTF-8。然而,绝大多数基于JSON的软件实现都选择使用UTF-8编码,因为它是实现互操作性的唯一编码。

——【implementations】不能在网络传输的JSON文本的开头添加字节顺序标记(U+FEFF)。为了实现互操作性,解析JSON文本的实现可能忽略字节顺序标记的存在,而不是将其视为错误。

7.2.Unicode字符

——当在JSON文本中表示的所有字符串都由Unicode字符( 无论如何转义 )组成时,那么JSON文本是可互操作的,因为解析它的所有软件实现都将在对象和数组中的名称和字符串值的内容上达成一致。
——但是,该规范中的ABNF允许成员名称和字符串值包含不能编码Unicode字符的位序列;例如“\uDEAD”(一个未配对的UTF-16代理项)。例如,当库在不检查截断是否拆分代理项对的情况下截断UTF-16字符串时,就会观察到这种情况。接收包含这些值的JSON文本的软件的行为是不可预测的;例如,实现可能返回字符串值长度的不同值,甚至会遇到致命的运行时异常。

7.3.字符串比较

——通常需要软件实现来测试对象成员的名称是否相等。将文本表示转换为Unicode代码单元的序列,然后按代码单元进行数字比较的实现是可互操作的,因为在所有情况下,【implementations】都将同意两个字符串的相等或不平等。例如,将字符串与未转换的转义字符进行比较的实现可能会错误地发现“a\ \b”和“a\u005Cb”不相等。

8.解析器

——JSON解析器将JSON文本转换为另一种表示形式。JSON解析器必须接受符合JSON语法的所有文本。JSON解析器可以接受非JSON形式或扩展。
——【implementations】可以限制其接受的文本的大小,限制嵌套的最大深度,限制数字的范围和精度,对字符串的长度和字符内容设置限制。

C#中主要 Json API 如下:

 

System.Text.Json.Nodes(.Net 6.0+) System.Json (.Net core 2.0+)
Newtonsoft.Json(.Net core 3.0+)
JsonNode 字典结构
  JToken
JsonObject(继承JsonNode) 字典结构
JsonObject(继承JsonValue) JObject
JsonArray(继承JsonNode)list结构 JsonArray(继承JsonValue) JArray
JsonValue JsonValue JValue

以上内容来源: https://www.json.org/

JSON是JavaScript Object Notation的缩写,它是一种数据交换格式。

在JSON出现之前,大家一直用XML来传递数据。因为XML是一种纯文本格式,所以它适合在网络上交换数据。XML本身不算复杂,但是,加上DTD、XSD、XPath、XSLT等一大堆复杂的规范以后,任何正常的软件开发人员碰到XML都会感觉头大了,最后大家发现,即使你努力钻研几个月,也未必搞得清楚XML的规范。

终于,在2002年的一天,道格拉斯·克罗克福特(Douglas Crockford)同学为了拯救深陷水深火热同时又被某几个巨型软件企业长期愚弄的软件工程师,发明了JSON这种超轻量级的数据交换格式。

道格拉斯同学长期担任雅虎的高级架构师,自然钟情于JavaScript。他设计的JSON实际上是JavaScript的一个子集。在JSON中,一共就这么几种数据类型:

  • number:和JavaScript的number完全一致;
  • boolean:就是JavaScript的truefalse
  • string:就是JavaScript的string 一个 utf8 编码的字符串值
  • null:就是JavaScript的null
  • array:就是JavaScript的Array表示方式——[]
  • object:就是JavaScript的{ ... }表示方式。

Json value对应C#System.Text.Json 文档 中的类型:JsonValueKind枚举

Array 2

A JSON array.

False 6

The JSON value false.

Null 7

The JSON value null.

Number 4

A JSON number.

Object 1

A JSON object.

String 3

A JSON string.

True 5

The JSON value true.

Undefined 0

There is no value (as distinct from Null).

Json value对应C#System.Json 节点 中的类型:JsonType枚举

Array 3  
Boolean 4  
Number 1  
Object 2  
String 0

以及上面的任意组合。

并且,JSON还定死了字符集必须是UTF-8,表示多语言就没有问题了。为了统一解析,JSON的字符串规定必须用双引号"",Object的键也必须用双引号""

由于JSON非常简单,很快就风靡Web世界,并且成为ECMA标准。几乎所有编程语言都有解析JSON的库,而在JavaScript中,我们可以直接使用JSON,因为JavaScript内置了JSON的解析。

把任何JavaScript对象变成JSON,就是把这个对象序列化成一个JSON格式的字符串,这样才能够通过网络传递给其他计算机。

如果我们收到一个JSON格式的字符串,只需要把它反序列化成一个JavaScript对象,就可以在JavaScript中直接使用这个对象了。

 

 【C# Json】System.Text.Json.Nodes ---Json数据交换格式 对应C#类  .net 6.0以后才出现的类型

 【C# Json】System.Json :.NET Platform Extensions 6 适用.NET Platform Extensions2.1, 2.2, 3.0, 3.1, 5, 6, 7 Preview 1

https://www.newtonsoft.com/json

posted @ 2022-03-12 15:00  小林野夫  阅读(620)  评论(0编辑  收藏  举报
原文链接:https://www.cnblogs.com/cdaniu/