JSON: JavaScript Object Notation(JavaScript 对象表示法)。JSON 是存储和交换文本信息的语法,类似 XML。JSON 比 XML 更小、更快,更易解析。JSON 易于人阅读和编写。
C#中转换JSON主要是用的几种方法:
C#通常用第四种,Newtonsoft.Json
1. Newtonsoft.Json
在程序中添加引用using Newtonsoft.Json,它提供了几个类型,JObject代表JSON对象,JObject是一个字典,其键是字符串(.NET对象的属性名),其值是JToken。JObject提供了索引访问。JSON对象的数组由JArray类型定义。
1.1 JSON语法
- 数据在名称/值对中
- 数据由逗号 , 分隔
- 大括号 {} 保存对象
- 中括号 [] 保存数组,数组可以包含多个对象([]里可以嵌套多个{})
- 使用斜杆 \ 来转义字符
1.1.1 JSON 的两种结构
1、对象:大括号 {} 保存的对象是一个无序的名称/值对集合。一个对象以左括号 { 开始, 右括号 } 结束。每个"键"后跟一个冒号 :,名称/值对使用逗号 , 分隔。
{ "name":"apple" , "age":2 }
2、数组:中括号 [] 保存的数组是值(value)的有序集合。一个数组以左中括号 [ 开始, 右中括号 ] 结束,值之间使用逗号 , 分隔。
{
"sites": [
{
"name": "菜鸟教程",
"url": "www.runoob.com"
},
{
"name": "google",
"url": "www.google.com"
},
{
"name": "微博",
"url": "www.weibo.com"
}
]
}
值(value)可以是双引号括起来的字符串(string)、数值(number)、true、false、 null、对象(object)或者数组(array),它们是可以嵌套。
1.1.2 JSON的值
- 数字(整数或浮点数)
- 字符串(在双引号中)
- 逻辑值(true 或 false)
- 数组(在中括号中)
- 对象(在大括号中)
- null
{
"name": "hope",
"age": 23,
"ischecked": true,
"title": null,
"filepath": "C:\\a.txt",
"sites": [
{
"name": "菜鸟教程",
"url": "www.runoob.com"
},
{
"name": "google",
"url": "www.google.com"
},
{
"name": "微博",
"url": "www.weibo.com"
}
]
}
1.2 .NET操作JSON
JSON文件读入到内存中就是字符串,.NET操作JSON就是生成与解析JSON字符串。
1.2.1 JsonReader读JSON字符串
string jsonText = @"[{""name"":""apple"",""sex"":""f"",""age"":2,""Books"":[{""bookName"":""骆驼祥子"",""bookPrice"":""34.7""},{""bookName"":""羊脂球"",""bookPrice"":""12""},{""bookName"":""格列佛游记"",""bookPrice"":""23.9""}]}]";
JsonReader reader = new JsonTextReader(new StringReader(jsonText));
while (reader.Read())
{
//reader.TokenType = StartArray reader.TokenType = StartObject
//reader.ValueType = null
//reader.Value = null
Console.WriteLine(reader.TokenType + "\t\t" + reader.ValueType + "\t\t" + reader.Value + "\r\n");
}
1.2.2 使用JsonWriter写JSON字符串
StringWriter sw = new StringWriter();
JsonWriter writer = new JsonTextWriter(sw);
writer.WriteStartObject();
writer.WritePropertyName("name");
writer.WriteValue("apple");
writer.WritePropertyName("sex");
writer.WriteValue("f");
writer.WriteEndObject();
writer.Flush();
//jsonText "{\"name\":\"apple\",\"sex\":\"f\"}" string
string jsonText = sw.GetStringBuilder().ToString();
1.2.3 使用JObject读写JSON字符串(包含JArray)
JObject中可能包含数组JArray,或者直接处理数组JArray
string jsonText = "{\"name\":\"apple\",\"sex\":\"f\",\"age\":2,\"Books\":[{\"bookName\":\"骆驼祥子\",\"bookPrice\":\"34.7\"},{\"bookName\":\"羊脂球\",\"bookPrice\":\"12\"},{\"bookName\":\"格列佛游记\",\"bookPrice\":\"23.9\"}]}";
JObject jo = JObject.Parse(jsonText);
//name:"apple"
string name = jo["name"].ToString();
//bookprice "{\r\n \"bookName\": \"骆驼祥子\",\r\n \"bookPrice\": \"34.7\"\r\n}"
string bookprice = jo["Books"][0].ToString();
//把数组单独取出来,处理数组
JObject jo1 = (JObject)JsonConvert.DeserializeObject(jsonText);
string book = jo1["Books"].ToString();
JArray ja = (JArray)JsonConvert.DeserializeObject(book);
//price:34.7
string price = ja[0]["bookPrice"].ToString();
JArray取值操作
string jsonText = @"[{""name"":""apple"",""sex"":""f"",""age"":2,""Books"":[{""bookName"":""骆驼祥子"",""bookPrice"":""34.7""},{""bookName"":""羊脂球"",""bookPrice"":""12""},{""bookName"":""格列佛游记"",""bookPrice"":""23.9""}]}]";
JArray ja = (JArray)JsonConvert.DeserializeObject(jsonText);
//bookname:骆驼祥子
string bookname = ja[0]["Books"][0]["bookName"].ToString();
1.2.4 JsonSerializer
JsonSerializer可以直接通过流的方式(读写JSON文件)来操作JSON数据
Person person = new Person();
person.date = new DateTime(2022, 11, 12);
JsonSerializer serializer = new JsonSerializer();
//指定转化日期的格式
serializer.Converters.Add(new JavaScriptDateTimeConverter());
//忽略空值
serializer.NullValueHandling = NullValueHandling.Ignore;
//1.将对象转化为JSON格式的字符串,然后存储到本地
//把json信息写入d:\json.txt中
using (StreamWriter sw = new StreamWriter(@"d:\json.txt"))
using (JsonWriter writer = new JsonTextWriter(sw))
{
serializer.Serialize(writer, person);
// {"age":0,"date":new Date(1668182400000)}
}
//2.将本地文件中的Json格式数据,转化为JObject对象
using (StreamReader sr = new StreamReader(@"d:\json.txt"))
using (JsonReader reader = new JsonTextReader(sr))
{
JObject jo = (JObject)serializer.Deserialize(reader);
}
1.2.5 Serializing and Deserializing JSON(序列化和反序列化JSON)
最常用的,效率最高的
Serializing序列化:对象转JSON字符串
Deserializing反序列化:JSON字符串转对象(可以是特定的对象,也可以用JObject)
string personJson = @"{""name"":""apple"",""sex"":""f"",""age"":2,""Books"":[{""bookName"":""骆驼祥子"",""bookPrice"":""34.7""},{""bookName"":""羊脂球"",""bookPrice"":""12""}]}";
string allPerJson = @"[{""name"":""apple"",""sex"":""f"",""age"":2,""Books"":[{""bookName"":""骆驼祥子"",""bookPrice"":""34.7""},{""bookName"":""羊脂球"",""bookPrice"":""12""},{""bookName"":""格列佛游记"",""bookPrice"":""23.9""}]},{""name"":""blue"",""sex"":""m"",""age"":1,""Books"":[{""bookName"":""骆驼"",""bookPrice"":""34.7""},{""bookName"":""羊"",""bookPrice"":""12""}]}]";
// 反序列化把JSON字符串变为Person对象 单个对象
Person per = JsonConvert.DeserializeObject<Person>(personJson);
// 反序列化 对象集合
List<Person> allPer = JsonConvert.DeserializeObject<List<Person>>(allPerJson);
//骆驼祥子
Console.WriteLine(per.Books[0].bookName);
//羊
Console.WriteLine(allPer[1].Books[1].bookName);
// 序列化,把对象转为JSON字符串
//"{\"name\":\"apple\",\"sex\":\"f\",\"age\":2,\"Books\":[{\"bookName\":\"骆驼祥子\",\"bookPrice\":\"34.7\"},{\"bookName\":\"羊脂球\",\"bookPrice\":\"12\"}]}"
string afterJson = JsonConvert.SerializeObject(personJson);
2. Newtonsoft.Json高级用法
Newtonsoft.Json高级用法 - 焰尾迭 - 博客园 (cnblogs.com)