.NET中解析JSON数据类型的全面指南**
在当今的软件开发中,JSON(JavaScript Object Notation)已成为数据交换的事实标准,它轻量、易读、易于解析和生成,因此在Web API、配置文件、数据存储等领域得到广泛应用。.NET框架为处理JSON数据提供了强大而灵活的支持,主要通过 System.Text.Json 命名空间(.NET Core 3.0+ 及更高版本推荐)和第三方库 Newtonsoft.Json( widely used and feature-rich)来实现,本文将详细介绍在.NET中如何使用这两种主流方式解析JSON数据类型。
为什么需要解析JSON?
JSON数据本质上是一个字符串,但它代表了特定的数据结构(如对象、数组、值等),当.NET应用程序需要从JSON字符串中提取数据、将其转换为.NET对象(如类、结构、集合等)以便在代码中使用时,就需要进行JSON解析,这个过程也称为“反序列化”(Deserialization)。
使用 System.Text.Json(.NET Core 3.0+ 推荐)
System.Text.Json 是.NET官方推出的高性能JSON库,旨在替代之前的 Newtonsoft.Json 成为默认选择,它无需额外安装(在.NET Core 3.0+及.NET 5/6/7/8等现代.NET版本中已内置),性能优异,且对.NET类型系统有很好的支持。
基本概念
- JsonSerializer: 核心类,提供序列化和反序列化的静态方法。
- JsonDocument: 提供了一种基于DOM(文档对象模型)的方式来读取和解析JSON,适用于需要灵活查询或处理大型JSON文档的场景,因为它不会立即将整个JSON反序列化为.NET对象。
- Utf8JsonReader: 提供了一种高性能的、只进、只读的方式来解析JSON流,适用于内存敏感或需要处理超大JSON文件的场景。
反序列化为.NET对象(最常用)
假设我们有以下JSON字符串:
{
"name": "张三",
"age": 30,
"isStudent": false,
"courses": ["数学", "物理", "化学"],
"address": {
"city": "北京",
"street": "长安街1号"
}
}
步骤:
a. 创建对应的.NET类型(类或结构)
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public bool IsStudent { get; set; }
public List<string> Courses { get; set; }
public Address Address { get; set; }
}
public class Address
{
public string City { get; set; }
public string Street { get; set; }
}
注意:
- JSON属性名默认与.NET类的属性名匹配(区分大小写)。
- 如果JSON属性名与.NET属性名不同,可以使用
[JsonPropertyName("jsonPropertyName")]特性(需要using System.Text.Json.Serialization;)。
b. 使用 JsonSerializer.Deserialize 进行反序列化
using System;
using System.Text.Json;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
string jsonString = @"{
""name"": ""张三"",
""age"": 30,
""isStudent"": false,
""courses"": [""数学"", ""物理"", ""化学""],
""address"": {
""city"": ""北京"",
""street"": ""长安街1号""
}
}";
try
{
Person person = JsonSerializer.Deserialize<Person>(jsonString);
if (person != null)
{
Console.WriteLine($"姓名: {person.Name}");
Console.WriteLine($"年龄: {person.Age}");
Console.WriteLine($"是否学生: {person.IsStudent}");
Console.WriteLine("课程:");
foreach (var course in person.Courses)
{
Console.WriteLine($" - {course}");
}
Console.WriteLine($"地址: {person.Address.City}, {person.Address.Street}");
}
}
catch (JsonException ex)
{
Console.WriteLine($"JSON解析错误: {ex.Message}");
}
}
}
使用 JsonDocument 灵活解析
如果不想预先定义完整的.NET类型,或者JSON结构动态变化,可以使用 JsonDocument。
using System;
using System.Text.Json;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
string jsonString = @"{
""name"": ""李四"",
""age"": 25,
""isStudent"": true,
""courses"": [""历史"", ""地理""]
}";
try
{
using JsonDocument doc = JsonDocument.Parse(jsonString);
JsonElement root = doc.RootElement;
string name = root.GetProperty("name").GetString();
int age = root.GetProperty("age").GetInt32();
bool isStudent = root.GetProperty("isStudent").GetBoolean();
Console.WriteLine($"姓名: {name}");
Console.WriteLine($"年龄: {age}");
Console.WriteLine($"是否学生: {isStudent}");
Console.WriteLine("课程:");
JsonElement coursesElement = root.GetProperty("courses");
foreach (JsonElement course in coursesElement.EnumerateArray())
{
Console.WriteLine($" - {course.GetString()}");
}
// 如果属性可能不存在,可以使用 TryGetProperty
if (root.TryGetProperty("address", out JsonElement addressElement))
{
Console.WriteLine($"地址: {addressElement.GetProperty("city").GetString()}");
}
else
{
Console.WriteLine("地址信息不存在");
}
}
catch (JsonException ex)
{
Console.WriteLine($"JSON解析错误: {ex.Message}");
}
}
}
System.Text.Json 常用特性
[JsonPropertyName("name")]: 指定JSON属性名与.NET属性名的映射。[JsonIgnore]: 忽略该属性,不参与序列化/反序列化。[JsonInclude]: 显式包含属性(通常用于只读属性)。[JsonConverter(typeof(MyConverter))]: 指定自定义的JSON转换器。
使用 Newtonsoft.Json (Json.NET)
尽管 System.Text.Json 是官方推荐,但 Newtonsoft.Json(也称Json.NET)因其悠久的历史、丰富的特性和良好的社区支持,在许多项目中仍然被广泛使用,它需要通过NuGet包管理器安装:Install-Package Newtonsoft.Json。
反序列化为.NET对象
使用 JsonConvert.DeserializeObject<T>() 方法。
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
string jsonString = @"{
""name"": ""王五"",
""age"": 28,
""isStudent"": false,
""courses"": [""美术"", ""音乐""]
}";
try
{
Person person = JsonConvert.DeserializeObject<Person>(jsonString);
if (person != null)
{
Console.WriteLine($"姓名: {person.Name}");
Console.WriteLine($"年龄: {person.Age}");
Console.WriteLine($"是否学生: {person.IsStudent}");
Console.WriteLine("课程:");
foreach (var course in person.Courses)
{
Console.WriteLine($" - {course}");
}
}
}
catch (JsonException ex)
{
Console.WriteLine($"JSON解析错误: {ex.Message}");
}
}
}
// Person类定义同 System.Text.Json 示例
Newtonsoft.Json 常用特性
[JsonProperty("name")]: 指定JSON属性名。[JsonIgnore]: 忽略属性。[JsonConverter(typeof(MyConverter))]: 指定自定义转换器。[DefaultValue("")]: 设置默认值。- 更多高级特性如
[JsonArray],[JsonObject]等。
处理复杂JSON数据类型
动态对象 (dynamic)
当JSON结构完全不确定,或者只需要临时访问JSON数据时,可以使用 dynamic 类型。
System.Text.Json:
JsonElement root = JsonDocument.Parse(jsonString).RootElement; dynamic dynamicObj = JsonElement.DynamicConverter.ToDynamic(root); // 注意:System.Text.Json本身不直接支持dynamic反序列化,需要额外转换或使用JsonNode (.NET 6+) // 或者使用 JsonNode (.NET 6+) JsonNode node = JsonNode.Parse(jsonString); string name = node["name"]?.GetValue<string>();
Newtonsoft.Json:
dynamic dynamicObj = JsonConvert.DeserializeObject<dynamic>(jsonString); string name = dynamicObj.name; int age = dynamicObj.age;
字典 (Dictionary)
JSON对象可以很容易地反序列化为 Dictionary<string, T>。
// 假设 JSON 是 {"key1": "value1", "key2": "value2"}
Dictionary<string, string> dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonString);
枚举 (Enum)
JSON字符串可以反序列化为.NET枚举类型,只需确保JSON值与枚举名称或值



还没有评论,来说两句吧...