在C#中使用JSON

打印 上一主题 下一主题

主题 1012|帖子 1012|积分 3036

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
JSON简介

1. 什么是 JSON?


        JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。它的语法基于 JavaScript 对象表示法,简单、易读,同时被许多编程语言支持。只管它来源于 JavaScript,但它并不依靠于 JavaScript,许多语言(如 Python、Java、C#、PHP 等)都能够解析和生成 JSON。

常见用途:
API 数据交互:在客户端和服务器之间传递数据时,JSON 是常用格式,特殊是前后端交互时.
配置文件:许多应用步伐使用 JSON 来生存配置文件(比方 .json 文件)。
数据恒久化:在数据库或文件体系中使用 JSON 来存储结构化数据。

2. JSON 的根本语法结构

JSON 的数据结构非常简单,重要包罗以下两种类型:

对象(Object):由花括号 {} 包围的一组键值对,键是字符串,值可以是任何合法的 JSON 数据类型。
数组(Array):由方括号 [] 包围的一组值,值可以是任意 JSON 类型。
示例:

  1. {
  2.   "name": "John",
  3.   "age": 30,
  4.   "isStudent": false,
  5.   "courses": ["Math", "Science"],
  6.   "address": {
  7.     "city": "New York",
  8.     "zipcode": "10001"
  9.   }
  10. }
复制代码
JSON 的根本元素:
字符串:用双引号包裹,如 "name": "John"
数字:可以是整数或浮点数,如 "age": 30
布尔值:true 或 false
数组:一个有序的值列表,用方括号 [] 包裹
对象:一个无序的键值对聚集,用花括号 {} 包裹
空值:null

你不难看出JSON 本质上由三种重要元素构成:
对象(Object):键值对的聚集,类似于字典。JSON 对象用 {} 表示,包含键值对(key-value pairs),键必须是字符串,值可以是任意合法的 JSON 元素(如数组、对象或根本值)。
数组(Array):有序的元素聚集,类似于列表或数组(不代表C#的数组,只是体现一个有序聚集)。JSON 数组用 [] 表示,数组中的每个元素可以是任意合法的 JSON 元素(如对象、数组或根本值)。
根本值(Value):JSON 的最基础元素,可以是字符串、数字、布尔值或 null。这部分数据不能再包含其他子元素。
这很紧张:因为充分分析这三种元素自身以及他们之间的关系是JSON处置惩罚的关键.很多JSON库也是考虑了这三种概念实现的.
3. JSON 的上风(作用)

JSON 之所以成为数据交换的首选格式,离不开它的诸多上风:

轻量级:相比于 XML 等格式,JSON 占用的体积更小,结构更为简便。
可读性好:人类易读,同时解析步伐也易于编写。
支持数据类型丰富:可以直接表示对象、数组、字符串、数字、布尔值等常见的数据结构。
广泛支持:险些所有编程语言都提供了用于解析和生成 JSON 的库或内置函数。
标准化格式:JSON 的格式有明确的标准,确保了跨语言、跨平台的兼容性。
机动性高:可以嵌套任意复杂的对象和数组,得当复杂的数据结构。

4. JSON 的常见使用场景


API 通信

在现代 Web 开发中,前后端的通信常常依靠于 JSON。客户端发送 HTTP 请求时,通常使用 JSON 格式来传递数据,服务器也通过 JSON 格式返回数据。下面是一个简单的例子:

请求体(客户端向服务器发送的数据):

  1. {
  2.   "username": "john_doe",
  3.   "password": "123456"
  4. }
复制代码
响应体(服务器返回的数据):

  1. {
  2.   "status": "success",
  3.   "message": "Login successful",
  4.   "token": "abcdef123456"
  5. }
复制代码
配置文件

JSON 格式经常用于存储配置数据,因为它易于阅读和修改。比方,一个应用步伐的配置文件可能如下:
  1. {
  2.   "app_name": "MyApp",
  3.   "version": "1.0.0",
  4.   "settings": {
  5.     "theme": "dark",
  6.     "language": "en"
  7.   }
  8. }
复制代码

本地数据存储

前端开发中,JSON 常被用来在本地存储数据(如浏览器的 localStorage 或 sessionStorage)。

数据序列化

当将对象或数据结构生存到文件或数据库时,通常需要将其序列化为字符串格式,JSON 就是常用的序列化格式之一。

5.JSON和C#类型之间的映射关系

在 C# 中,JSON 的根本元素与相应的数据类型有直接的对应关系。
1. 字符串
JSON:字符串用双引号包裹,表示文本数据。
示例:"name": "John"

C# 对应类型:string
在 C# 中,JSON 的字符串类型直接映射为 string 类型。
示例:
  1. string name = "John";
复制代码

2. 数字
JSON:数字可以是整数或浮点数,表示数值类型的数据。
示例:"age": 30

C# 对应类型:int、float、double
在 C# 中,整数可以映射为 int,浮点数可以映射为 float 或 double,根据具体需要选择类型。
示例:
  1. int age = 30;
  2. float price = 29.99f;
  3. double pi = 3.14159;
复制代码

3. 布尔值
JSON:布尔值表示为 true 或 false。
示例:"isStudent": false

C# 对应类型:bool
在 C# 中,布尔值映射为 bool 类型。
示例:
  1. bool isStudent = false;
复制代码

4. 数组
JSON:数组是一个有序的值列表,用方括号 [] 包裹,数组中的每个元素可以是任意 JSON 类型。
示例:"courses": ["Math", "Science"]

C# 对应类型:List<T> 或数组 T[]
在 C# 中,JSON 数组可以映射为 List<T>(泛型列表)大概平凡数组 T[],此中 T 是数组中元素的类型。
示例:
  1. List<string> courses = new List<string> { "Math", "Science" };
  2. // 或者
  3. string[] coursesArray = { "Math", "Science" };
复制代码

5. 对象
JSON:对象是一个无序的键值对聚集,用花括号 {} 包裹,每个键必须是字符串,值可以是任意 JSON 类型。
示例:"address": { "city": "New York", "zipcode": "10001" }

C# 对应类型:自定义类或 Dictionary<string, T>
在 C# 中,JSON 对象可以映射为自定义类,类中的属性对应 JSON 对象中的键值对。也可以使用 Dictionary<string, T> 来表示键值对聚集,此中 T 表示值的类型。
示例(使用自定义类):
  1. class Address
  2. {
  3.     public string City { get; set; }
  4.     public string Zipcode { get; set; }
  5. }
  6. Address address = new Address { City = "New York", Zipcode = "10001" };
复制代码

示例(使用字典):
  1. Dictionary<string, string> address = new Dictionary<string, string>
  2. {
  3.     { "city", "New York" },
  4.     { "zipcode", "10001" }
  5. };
复制代码

6. 空值
JSON:空值表示为 null。
示例:"middleName": null

C# 对应类型:null
在 C# 中,JSON 的 null 对应 C# 中的 null 值。它可以应用于任何可空类型(如引用类型和 Nullable<T>)。

在 C# 中,JSON 的根本元素可以映射为相应的 C# 数据类型。这种映射使得我们可以轻松处置惩罚 JSON 数据,并与 C# 中的对象和类型进行交互。

6. 如那边理 JSON 数据

什么是序列化/反序列化

        我们首先要先铺垫一下什么是序列化/反序列化
        序列化反序列化是将对象和数据在不同格式之间转换的过程,重要用于数据恒久化、网络传输等场景.在C#中我们的数据一般以对象情势存储在内存中,但是内存数据不能恒久生存,你关机后大概步伐关闭时数据就没了,那我们怎么把数据生存下来呢?
        答案就是序列化,我们常用的就是将对象序列化为JSON(当然不止JSON,只是JSON更常用),如许我们再将其(这个说的更清楚点就是字符串,JSON绝大多数情况是以字符串情势出现的,只不过你可以理解为是一种有肯定格式或肯定规则的字符串)生存在磁盘大概通过网络传递给其他人都很方便.
        理所当然的JSON转换为内存中的对象就是反序列化,常见的情景就是读取JSON格式的配置文件,先从磁盘读取出来再反序列化为对象,我们就可以十分方便的操纵这个对象了.

怎么做?

        大多数编程语言都提供了用于解析(反序列化)和生成(序列化)JSON 数据的库或内置函数。
C# 提供了 System.Text.Json 和 Newtonsoft.Json(第三方库)来处置惩罚 JSON。
        我建议使用Newtonsoft.Json(NuGet Gallery | Newtonsoft.Json 13.0.3),这可以说是C#环境里最流行,最强盛的一个库,经过二十年左右的发展支持绝大多数.net环境,现在在所有nuget包中下载量中排名第一.
常见用法
1. 使用 JsonConvert.SerializeObject 方法可以将 C# 对象转换为 JSON 字符串。
  1. using Newtonsoft.Json;
  2. public class Person
  3. {
  4.     public string Name { get; set; }
  5.     public int Age { get; set; }
  6.     public bool IsStudent { get; set; }
  7. }
  8. Person person = new Person { Name = "John", Age = 30, IsStudent = false };
  9. // 序列化为 JSON
  10. string json = JsonConvert.SerializeObject(person);
  11. Console.WriteLine(json);
复制代码
得到(这就是一个字符串,包罗首尾的花括号在内,前面提到{}代表一个对象,内里是无序的键值对)
  1. {"Name":"John","Age":30,"IsStudent":false}
复制代码
2.  使用 JsonConvert.DeserializeObject<T> 可以将 JSON 字符串反序列化为 C# 对象。
  1. //这里的\是转义符,不是字符串自身的内容
  2. string json = "{"Name":"John","Age":30,"IsStudent":false}";
  3. // 反序列化为对象
  4. Person person = JsonConvert.DeserializeObject<Person>(json);
  5. Console.WriteLine(person.Name);  // 输出 "John"
  6. Console.WriteLine(person.Age);   // 输出 30
复制代码
3.  将 JSON 数组转换为 C# 聚集(如 List<T>)。
  1. string jsonArray = "[{"Name":"John","Age":30},{"Name":"Jane","Age":25}]";
  2. // 反序列化为 List<Person>
  3. List<Person> people = JsonConvert.DeserializeObject<List<Person>>(jsonArray);
  4. foreach (var person in people)
  5. {
  6.     Console.WriteLine($"{person.Name}, {person.Age}");
  7. }
复制代码
  1. John, 30
  2. Jane, 25
复制代码
4. 处置惩罚嵌套对象
如果 JSON 中包含嵌套对象,Newtonsoft.Json 可以自动反序列化嵌套结构。
  1. public class Address
  2. {
  3.     public string City { get; set; }
  4.     public string Zipcode { get; set; }
  5. }
  6. public class Person
  7. {
  8.     public string Name { get; set; }
  9.     public Address Address { get; set; }
  10. }
  11. string nestedJson = "{"Name":"John","Address":{"City":"New York","Zipcode":"10001"}}";
  12. // 反序列化嵌套的 JSON
  13. Person person = JsonConvert.DeserializeObject<Person>(nestedJson);
  14. Console.WriteLine($"{person.Name} lives in {person.Address.City}, {person.Address.Zipcode}");
复制代码
5.JToken,JObject,JArray,JValue
上面提到JSON的根本构成元素:对象,数组,根本值,这对应看newtonjson提供的JObject,JArray,JValue三种类型,哪还有一个JToken,这个JToken是三种类型抽象类型,后三者继承自前者.
为什么提到这些类呢?因为更机动!
        你注意上面例子,我们处置惩罚一个JSON需要先声明一个类型,有的时间我们声明了这个类型可能极少使用,那么这个时间我们声明一个类型似乎就有些没须要了.
        大概这个JSON数据的结构不是固定的,或是动态的的情况下.所以我们使用上面的类型.
  1. string jsonString = "{"name": "Alice", "age": 25}";
  2. // 使用 JObject 解析
  3. JObject obj = JObject.Parse(jsonString);
  4. // 动态访问字段
  5. string name = (string)obj["name"];
  6. int age = (int)obj["age"];
  7. Console.WriteLine($"Name: {name}, Age: {age}");
复制代码
        请看JSON代表一个对象,如果不常用这个类型,那么我们直接以为它是一个JObject类型.如许我们转为JObject类型,再使用索引器直接拿到我们需要的数据.

        上述我们知道这是一个对象,所以我们使用JObject类型,那么我们连这个也不知道呢?无妨!掏出我们的JToken类型,这个类型是三个子类的父类,包含所有子类的举动,能够代表所有的JSON概念,无论它是对象,数组,照旧根本值.
        
  1. using Newtonsoft.Json.Linq;
  2. string jsonString = @"{
  3.     'person': {
  4.         'name': 'Alice',
  5.         'age': 25,
  6.         'address': {
  7.             'city': 'Wonderland',
  8.             'zipcode': '12345'
  9.         },
  10.         'phones': ['123-456-7890', '987-654-3210']
  11.     }
  12. }";
  13. // 解析为 JToken
  14. JToken token = JToken.Parse(jsonString);
  15. // 动态访问嵌套字段
  16. string name = (string)token["person"]["name"];
  17. string city = (string)token["person"]["address"]["city"];
  18. string phone = (string)token["person"]["phones"][0];
  19. Console.WriteLine($"Name: {name}, City: {city}, First Phone: {phone}");
复制代码
  1. using Newtonsoft.Json.Linq;
  2. string jsonString = @"{
  3.     'name': 'Alice',
  4.     'age': 25,
  5.     'address': {
  6.         'city': 'Wonderland',
  7.         'zipcode': '12345'
  8.     },
  9.     'hobbies': ['reading', 'chess', 'running']
  10. }";
  11. // 使用 JToken 解析
  12. JToken token = JToken.Parse(jsonString);
  13. // 动态访问对象中的字段
  14. string name = (string)token["name"];
  15. int age = (int)token["age"];
  16. // 动态访问嵌套对象
  17. string city = (string)token["address"]["city"];
  18. string zipcode = (string)token["address"]["zipcode"];
  19. // 动态访问数组中的元素
  20. string firstHobby = (string)token["hobbies"][0];
  21. string secondHobby = (string)token["hobbies"][1];
  22. // 输出结果
  23. Console.WriteLine($"Name: {name}, Age: {age}");
  24. Console.WriteLine($"City: {city}, Zipcode: {zipcode}");
  25. Console.WriteLine($"First Hobby: {firstHobby}, Second Hobby: {secondHobby}");
复制代码
类型转换(对于JToken或它的子类)

        Newtonsoft.Json 不但支持通过类型逼迫转换访问 JSON 数据,还提供了更加便捷的方法来进行类型转换。这些方法能够克制类型逼迫转换时潜伏的异常风险,并提供更清楚的代码表达。
Newtonsoft.Json 提供了以下常用的类型转换方法
1.Value<T>() 方法(适用于根本类型)
        Value<T>() 是 JToken 提供的一个泛型方法,能够安全地将 JToken 的值转换为指定的类型。如果类型转换失败,它不会抛出异常,而是返回类型的默认值。
适用于想要克制显式的类型逼迫转换,并且希望代码更简便、安全的场景。
  1. JToken token = JToken.Parse(@"{ 'name': 'Alice', 'age': 25 }");
  2. string name = token["name"].Value<string>(); // 安全的类型转换
  3. int age = token["age"].Value<int>(); // 转换为 int
  4. Console.WriteLine($"Name: {name}, Age: {age}");
复制代码

        使用 Value<T>() 进行转换时,如果值不存在大概转换失败,它会返回类型的默认值(如 string 会返回 null,int 会返回 0),不会像类型逼迫转换那样抛出异常。

2.ToObject<T>() 方法
        ToObject<T>() 是另一个常用的方法,答应将 JToken 转换为一个具体的对象或类型。它适用于你希望将 JSON 数据反序列化为 C# 的具体类型(如类或结构体)的场景。
ToObject<T>() 方法通过反序列化来进行转换,因此得当用于复杂的数据结构转换。
  1. // 定义一个类与 JSON 数据对应
  2. public class Person
  3. {
  4. public string Name { get; set; }
  5. public int Age { get; set; }
  6. }
  7. JToken token = JToken.Parse(@"{ 'name': 'Alice', 'age': 25 }");
  8. // 将 JToken 反序列化为具体的 Person 对象
  9. Person person = token.ToObject<Person>();
  10. Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");
复制代码

得当处置惩罚复杂的 JSON 数据结构,能够将整个 JSON 结构直接转换为一个 C# 对象。
它的机动性使得你可以轻松地从 JSON 数据中创建 C# 类对象,而不用手动提取每一个字段。
3.TryGetValue<T>(out T result) 方法
        这是一个较为安全的访问方式,TryGetValue 实验从 JToken 中获取指定类型的值,并通过返回布尔值来指示是否乐成获取。
它得当在不确定 JSON 数据结构或类型时,安全地进行转换操纵,克制抛出异常。
  1. JToken token = JToken.Parse(@"{ 'name': 'Alice', 'age': 'not an integer' }");
  2. // 尝试安全获取值
  3. int age;
  4. bool success = token["age"].TryGetValue<int>(out age);
  5. if (success)
  6. {
  7. Console.WriteLine($"Age: {age}");
  8. }
  9. else
  10. {
  11. Console.WriteLine("Failed to get a valid integer for age.");
  12. }
复制代码

安全的类型转换方式,得当在 JSON 数据不可靠或结构复杂时使用。
它通过 out 参数来返回效果,能够克制异常。
逼迫类型转换 vs 提供的方法
逼迫类型转换(Explicit Casting)
        答应直接进行逼迫类型转换,比如 (string)token["name"] 或 (int)token["age"]。这种方式比较简便,但是如果类型不匹配或值不存在,会抛出异常。
总结
Value<T>() 方法:提供了安全的类型转换方式,不会抛出异常,得当处置惩罚简单的数据访问场景,代码简便。

ToObject<T>() 方法:得当将 JSON 直接转换为 C# 对象,特殊是对于复杂的 JSON 结构,能够镌汰手动提取每个字段的工作量。

TryGetValue<T>() 方法:提供一种安全的方式来获取 JSON 数据中的值,得当在不确定命据结构或类型的情况下使用,防止异常的发生。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

羊蹓狼

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表