在C#的开发场景中,处理JSON数据是非常常见的需求,很多时候我们只需要读取JSON中的内容而不需要对其进行修改,这时候使用JsonDocument实现只读解析会比其他可修改的JSON解析方式更高效,内存占用也更低。JsonDocument是.NET Core 3.0之后引入的System.Text.Json命名空间下的核心类型,专门用于处理只读的JSON文档,它提供了快速的JSON解析能力和便捷的节点访问方式。

JsonDocument的基本使用步骤
1. 加载JSON数据
JsonDocument提供了多个静态方法来加载JSON数据,最常用的是Parse方法,它可以接收JSON字符串或者ReadOnlyMemory<byte>、Stream等类型的输入。
using System;
using System.Text.Json;
class Program
{
static void Main()
{
// 待解析的JSON字符串
string jsonStr = @"
{
"name": "测试用户",
"age": 25,
"hobbies": ["阅读", "运动", "编程"],
"address": {
"city": "北京",
"street": "测试路123号"
}
}";
// 解析JSON字符串得到JsonDocument实例
using JsonDocument doc = JsonDocument.Parse(jsonStr);
Console.WriteLine("JSON解析完成");
}
}
2. 访问根节点和属性
解析完成后,可以通过RootElement属性获取JSON的根节点,根节点是JsonElement类型,通过它可以访问JSON中的所有内容。
using System;
using System.Text.Json;
class Program
{
static void Main()
{
string jsonStr = @"
{
"name": "测试用户",
"age": 25,
"hobbies": ["阅读", "运动", "编程"],
"address": {
"city": "北京",
"street": "测试路123号"
}
}";
using JsonDocument doc = JsonDocument.Parse(jsonStr);
JsonElement root = doc.RootElement;
// 获取name属性的值
string name = root.GetProperty("name").GetString();
Console.WriteLine($"姓名:{name}");
// 获取age属性的值
int age = root.GetProperty("age").GetInt32();
Console.WriteLine($"年龄:{age}");
}
}
3. 遍历数组和嵌套对象
如果JSON中包含数组或者嵌套对象,可以通过JsonElement的对应方法来遍历和访问。
using System;
using System.Text.Json;
class Program
{
static void Main()
{
string jsonStr = @"
{
"name": "测试用户",
"age": 25,
"hobbies": ["阅读", "运动", "编程"],
"address": {
"city": "北京",
"street": "测试路123号"
}
}";
using JsonDocument doc = JsonDocument.Parse(jsonStr);
JsonElement root = doc.RootElement;
// 遍历hobbies数组
Console.WriteLine("爱好列表:");
JsonElement hobbies = root.GetProperty("hobbies");
foreach (JsonElement hobby in hobbies.EnumerateArray())
{
Console.WriteLine($"- {hobby.GetString()}");
}
// 访问嵌套的address对象
JsonElement address = root.GetProperty("address");
string city = address.GetProperty("city").GetString();
string street = address.GetProperty("street").GetString();
Console.WriteLine($"地址:{city} {street}");
}
}
JsonDocument的注意事项
- JsonDocument实例实现了
IDisposable接口,使用完成后需要及时释放,建议使用using语句包裹,避免内存泄漏。 - JsonDocument是只读的,无法修改解析后的JSON内容,如果需要修改JSON数据,应该选择
JsonNode或者其他可修改的JSON解析方案。 - 获取属性时如果属性不存在,
GetProperty方法会抛出KeyNotFoundException,可以先使用TryGetProperty方法判断属性是否存在。
using System;
using System.Text.Json;
class Program
{
static void Main()
{
string jsonStr = "{"name": "测试用户"}";
using JsonDocument doc = JsonDocument.Parse(jsonStr);
JsonElement root = doc.RootElement;
// 安全获取属性
if (root.TryGetProperty("age", out JsonElement ageElement))
{
int age = ageElement.GetInt32();
Console.WriteLine($"年龄:{age}");
}
else
{
Console.WriteLine("未找到age属性");
}
}
}
JsonDocument与其他解析方式对比
和JsonSerializer反序列化为实体类的方式相比,JsonDocument不需要提前定义实体类,适合处理结构不固定的JSON数据;和Newtonsoft.Json的JObject相比,JsonDocument的内存占用更低,解析速度更快,但是功能相对简单,仅支持只读操作。
| 解析方式 | 是否需要实体类 | 是否支持修改 | 内存占用 | 解析速度 |
|---|---|---|---|---|
| JsonDocument | 否 | 否 | 低 | 快 |
| JsonSerializer反序列化 | 是 | 是(修改实体后重新序列化) | 中 | 中 |
| JObject | 否 | 是 | 高 | 慢 |
JsonDocumentC#_JSON解析只读_JSONSystem_Text_Json修改时间:2026-06-15 13:36:17