ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

newtonsoft.json

2020-09-12 16:32:40  阅读:257  来源: 互联网

标签:newtonsoft Json JsonConvert json JValue 类型 new


大纲

程序 = 数据结构 + 算法,可以理解成,程序 = 变量 + 方法;方法就像一个黑盒,变量流入黑盒,经过方法加工再流出。

所以,程序是由众多变量和方法构成的,那怎么组织这些繁杂的变量和方法呢?

面向对象的编程语言,变量也被封装进一个个的类中,此时,可以把类看作是一个数据包而已,静态变量和实例变量不同;通过【new 数据包】构造一个全新的数据包,从而在整个应用程序中,实例变量可以有很多份;静态变量只有一份。将方法分门别类放到各个类中组织起来,静态方法和实例方法没什么区别,都是被圈禁在类中的方法。只是静态方法只能流入静态变量,实例方法可以流入静态或实例变量。

数据存储在数据库,相当于存储在仓库;数据存储在磁盘,相当于存储在背包;数据存储在变量,相当于拿在手里。一份数据不管存储在哪里,在提供给方法使用时,是完全等价,表示完全相同的意义。有一种特殊格式的数据,可以放进数据库,磁盘,内存(被类组织起来的变量,相当于数据包)中,三个地方的表示方法不同,但是相互映射,完全等价,这种格式就叫Json。

类是一种数据包,能够封装不同类型的数据,数组也是一种数据包,能够封装相同类型的数据。

Json是一种基于字面值的对象表示法,是一种数据交换格式。

Json是文本,可以描述一个类,可以存储在磁盘,放在磁盘可以记录状态,可持续化,在需要的时候转换成内存中的对象使用。

C++ 和 C#是两种不同的语言,二者的数据类型不同。Json有6种数据类型【数字】【字符串】【布尔】【null】【对象】【数组】,Json是中介,C++可以将Json的类型解读成自己的类型,或者将自己的类型解析成Json类型,C#同样可以,这样,C++和C#就可以交互数据了。这如同日本人和中国人通过英文相互交流,中国人将汉语转换成英文对日本人说,日本人听到英文,将英文翻译成日文,然后理解了中国人说了什么,反之亦然。

什么叫字面量(literal)?5就是5,称为字面量。x = 5,x是变量,不是字面量。

Json的数字,字符串,布尔,null都是字面值,字面值再组成数组和对象。对象是不同类型的数据的集合,数组是相同类型的数据的集合。再复杂的数据类型拆开后,都是由字面量组成的。

json表示对象时,属性名(key)必须用双引号包裹,对于Json而言,key名可以包含空格,#,%等字符串,但是为了兼容更多的语言,尽量不要使用特殊字符,数字字母下划线最好,。 value如果是字符串类型,可以是任何形式任何字符。value并不需要总被双引号包裹,value是字符串时,必须使用双引号。如果是数字,布尔值,数组,对象,null,这些都不应被双引号包裹。

json的媒体类型是application/json

Json中字符串

json中的字符串类型必须用双引号包裹,不能是单引号。

字符串中含有双引号怎么办?

"promo" : " "hello world" " 这种表示是错的

"promo" : " "hello world" "

字符串中含有\怎么办?

"location" : "C:\program files"

"location" : "C:\program files"

除了双引号和反斜线,还需要转义的字符

\b 退格符

\f 换页符

\t 制表符

\n 换行符

\r 回车符

\u后面跟十六进制字符 (\u263A)

Json中的数字

Json中的布尔

在json中布尔字面值必须是小写的,如"true" "false"。

Json中的null

null表示一个没有值的值,必须是小写。

Json中的数组

["str1","str2",null, 5.0] 这种表示对于json是合法的,但是我们应该尽量避免这样做,因为这种json数组可以被动态语言正确解析成列表数据类型,但是像C#,java,C++这种强类型语言无法解析成泛型数组或泛型列表数据类型。

三种系统描述同一种数据结构

Json是基于字面值的对象表示法的数据格式,有以下类型:

  1. 数字(1)
  2. 字符串("str")
  3. 布尔(true false)
  4. null(null)
  5. 数组[e1,e2]
  6. 对象{"p1":1,"p2":"ok","p3":[e1,e2]}

Linq to Json的类型有:

  1. 数字(new JValue(1))
  2. 字符串(new JValue("str"))
  3. 布尔(new JValue(true))
  4. null(JValue.CreateNull)
  5. JArray
  6. JObject

但是Linq to Json也提供一个JToken类型,它是JArray, JObject,JValue的基类,可以表示6个类型的任何一个。

.NET类型有:

  1. 数字(1)
  2. 字符串("str") DateTime TimeSpan Uri GUID 枚举
  3. 布尔(true)
  4. null(null)
  5. 线性列表容器(IList
  6. class Dictionary<TKey,TValue> DataSet

C# <=> Json <=> C++

C#和C++实现类型映射,是通过Json实现的。C#的某个类型Acsharp映射成Json的某个类型Ajson,如果C++的某个类型Acpp也映射成Json的类型Ajson,那么C#的类型Acsharp和C++的类型Acpp就实现了映射。Json共有6种类型,每种类型可以映射C#语言的多种类型,只要高级语言的类型可以映射成Json的某个类型,那高级语言的这个类型就可以和Json序列化和反序列化。

Json的数组的元素可以是不同类型,Linq to Json的JArray也可以容纳不同类型,.NET的线性列表类型如果是ArrayList可以映射Json和Linq to Json中元素类型不同的数组,如果是泛型的IList

.NET Type,Json,Linq to Json是独立又相互映射,核心思想是C++类型和C#类型通过Json为中介实现相互映射,可以通信。

用三种系统构建同一种数据结构时,各系统只能使用各自系统的类型进行增删改。

已知一种系统,能够快速构建完全等价的其他两种系统

1. Linq to Json <=> Json

利用Linq to Json快速构造指定的Json

指定的Json

{
  "MyArray": [
    1,
    false,
    null,
    [],
    "Manual text",
    "2020-09-11T21:23:10.4145426+08:00",
    "00:00:00.0000010",
    "C:\\\\d.txt"
  ]
}

方法一:Linq 2 Json的无参构造方法

JArray arr = new JArray();
arr.Add(new JValue(1));
arr.Add(new JValue(false));
arr.Add(JValue.CreateNull());
arr.Add(new JArray());
arr.Add(new JValue("Manual text"));
arr.Add(new JValue(DateTime.Now));
arr.Add(new JValue(new TimeSpan(10)));
arr.Add(new JValue(new Uri(@"C:\\d.txt")));
JObject obj = new JObject();
obj["MyArray"] = arr;

方法二:Linq to Json的构造方法的初始化器

JObject obj = new JObject()
{
    "MyArray",new JArray()
    {
        new JValue("Manual text"),
        new JValue(DateTime.Now),
        new JValue(1),
        new JValue(false),
        new JValue(new TimeSpan(10)),
        new JValue(new Uri(@"C:\\d.txt")),
        JValue.CreateNull(),
        new JArray()
    }
};

方法三: 利用JProperty

JObject obj = new JObject();
obj.Add
(
    new JProperty("MyArray", 
    new JArray() {
        new JValue("Manual text"),
        new JValue(DateTime.Now),
        new JValue(1), new JValue(true),
        JValue.CreateNull(),
        new JValue(new TimeSpan(10)),
        new JValue(new Uri(@"C:\\d.txt")),
        new JArray()
    })
 );

Linq to Json转换成Json

new JArray().ToString();
new JObject().ToString();
new JValue(1.0).ToString();
new JValue("str").ToString();
new JValue(true).ToString();
JValue.CreateNull().ToString();

利用Json快速构造指定的Linq to Json

Json转换成Linq to Json

string json = @"[
                   ""Small"",
                   ""Medium"",
                   ""Large""
                ]";
JArray arr = JArray.Parse(json);
JToken token = JToken.Parse(json);


json = @"{
           CPU: 'Intel',
           Drives: [
           'DVD read/writer',
           '500 gigabyte hard drive'
           ]
         }";
JObject obj = JObject.Parse(json);
token = JToken.Parse(json);


json = "1";
JValue value = JToken.Parse(json) as JValue;


json = "\"1\"";
value = JToken.Parse(json) as JValue;


json = "\"1\"";
value = JToken.Parse(json) as JValue;


json = "true";
value = JToken.Parse(json) as JValue;


json = "null";
value = JToken.Parse(json) as JValue;

得知每个Token的实际类型,JValue的实际类型. 递归遍历输出一个对象所有的基本类型的类型和值。

2. DotNET Type <=> Json

利用DotNET Type快速构造Json

指定的Json

[{"UserName":"test","Address":"gz"}]

方式一:采用匿名类型比较快速简洁

JsonConvert.SerializeObject(new ArrayList() { new
{
    UserName = "test",
    Address = "gz"
}});

方式二:

class Person
{
    public string UserName { get; set; }
    public string Address { get; set; }
}
JsonConvert.SerializeObject(new List<Person>() { new Person() { UserName = "test", Address = "gz"} });

DotNET Type转换成Json

public class Account
{
    public string Email { get; set; }
    public bool Active { get; set; }
    public DateTime CreatedDate { get; set; }
    public IList<string> Roles { get; set; }
}
Account account = new Account
{
    Email = "james@example.com",
    Active = true,
    CreatedDate = new DateTime(2013, 1, 20, 0, 0, 0, DateTimeKind.Utc),
    Roles = new List<string>
    {
        "User",
        "Admin"
    }
};
JsonConvert.SerializeObject(account, Formatting.Indented);
JsonConvert.SerializeObject(new List<Person>() { new Person() { UserName = "test", Address = "gz"} });
JsonConvert.SerializeObject(new Person() { UserName = "test", Address = "gz" });
JsonConvert.SerializeObject(1);
JsonConvert.SerializeObject(false);
JsonConvert.SerializeObject(null);
JsonConvert.SerializeObject("str");
JsonConvert.SerializeObject(DateTime.Now);
JsonConvert.SerializeObject(Guid.NewGuid());
JsonConvert.SerializeObject(new Uri("C:\\test.txt", UriKind.Absolute));

newtonsoft.json特殊处理过.NET的字典,它映射Json中的对象类型。DataSet也是同样。//TODO

字典序列化时,每个key的ToString()字符串作为属性名称,每个属性的值是字典的Value映射的Json类型。

Dictionary<Person, int> dic = new Dictionary<Person, int>();
dic[new Person() { UserName = "A", Address = "a" }] = 1;
dic[new Person() { UserName = "B", Address = "b" }] = 2;
JsonConvert.SerializeObject(dic);

利用Json快速构造DotNET Type

Json转换成DotNET Type

JsonConvert.DeserializeObject<int>("1");
JsonConvert.DeserializeObject<string>("\"str\"");
JsonConvert.DeserializeObject<bool>("false");
JsonConvert.DeserializeObject<ArrayList>("[]");
JsonConvert.DeserializeObject<object>("{}");
JsonConvert.DeserializeObject<Dictionary<string,int>>(@"{'A':1,'B':2}");
JsonConvert.DeserializeObject<Guid>("\"970a0dff-de1d-45da-9000-6d7c5c00f53f\"");
JsonConvert.DeserializeObject<Uri>(@"""C:\\test.txt""");
JsonConvert.DeserializeObject<Person>(@"{'UserName':'Danqing Zhu','Address':'周口 河南' }");

简洁方法

var definition = new { Name = "" };
string json1 = @"{'Name':'James'}";
var customer1 = JsonConvert.DeserializeAnonymousType(json1, definition);
Console.WriteLine(customer1.Name);
// James
string json2 = @"{'Name':'Mike'}";
var customer2 = JsonConvert.DeserializeAnonymousType(json2, definition);
Console.WriteLine(customer2.Name);
// Mike

3. Linq to Json <=> DotNET Type

利用Linq to Json快速构造DotNET Type

Linq to Json转换成DotNET Type

JObject.FromObject(new object());
JArray.FromObject(new List<string>());
JToken.FromObject(1);

利用DotNET Type快速构造Linq to Json

DotNET Type转换成Linq to Json

标签:newtonsoft,Json,JsonConvert,json,JValue,类型,new
来源: https://www.cnblogs.com/browsepearls/p/13657469.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有