C# System.Text.Json终极指南(十):从基础到高性能序列化实战
一、JSON序列化革命:System.Text.Json的架构优势
1.1 核心组件解析
1.2 性能基准测试(.NET 8)
操作 | Newtonsoft.Json | System.Text.Json | 性能提升 |
---|---|---|---|
简单对象序列化 | 1,200 ns | 450 ns | 2.7x |
大型对象反序列化 | 15 ms | 5.2 ms | 2.9x |
内存分配(1k次操作) | 45 MB | 12 MB | 3.75x |
二、基础序列化操作精解
2.1 基本序列化/反序列化
// 简单对象定义
public class Product
{public int Id { get; set; }public string Name { get; set; }public decimal Price { get; set; }
}// 序列化
var product = new Product { Id = 1, Name = "Laptop", Price = 999.99m };
string json = JsonSerializer.Serialize(product);// 反序列化
Product deserialized = JsonSerializer.Deserialize<Product>(json);
2.2 流式处理大文件
// 写入大型JSON
await using (var fs = File.Create("bigfile.json"))
{await JsonSerializer.SerializeAsync(fs, largeData);
}// 读取大型JSON
await using (var fs = File.OpenRead("bigfile.json"))
{var data = await JsonSerializer.DeserializeAsync<BigData>(fs);
}
三、高级配置与自定义
3.1 JsonSerializerOptions详解
var options = new JsonSerializerOptions
{PropertyNamingPolicy = JsonNamingPolicy.CamelCase, // 命名策略WriteIndented = true, // 美化输出DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, // 忽略nullConverters = { new DateTimeConverter() }, // 自定义转换器NumberHandling = JsonNumberHandling.AllowReadingFromString, // 数字处理ReferenceHandler = ReferenceHandler.Preserve // 循环引用处理
};
3.2 自定义转换器开发
public class DateTimeConverter : JsonConverter<DateTime>
{public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options){return DateTime.ParseExact(reader.GetString(), "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);}public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options){writer.WriteStringValue(value.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture));}
}
3.3 多态序列化策略
[JsonDerivedType(typeof(Student), "student")]
[JsonDerivedType(typeof(Teacher), "teacher")]
public class Person
{public string Name { get; set; }
}var people = new List<Person> { new Student(), new Teacher() };
string json = JsonSerializer.Serialize(people); // 自动处理类型标识
四、高性能序列化技巧
4.1 源码生成模式
// 定义可序列化上下文
[JsonSerializable(typeof(Product))]
public partial class AppJsonContext : JsonSerializerContext
{
}// 使用生成的序列化代码
var json = JsonSerializer.Serialize(product, AppJsonContext.Default.Product);
性能对比:
模式 | 100k次调用时间 | 内存分配 |
---|---|---|
反射模式 | 450 ms | 120 MB |
源码生成 | 120 ms | 15 MB |
4.2 池化技术应用
// 重用缓冲区
var buffer = new ArrayBufferWriter<byte>();
var writer = new Utf8JsonWriter(buffer);JsonSerializer.Serialize(writer, data);
ProcessBuffer(buffer.WrittenSpan);// 重置复用
writer.Reset();
buffer.Clear();
4.3 最佳性能配置
var highPerfOptions = new JsonSerializerOptions
{DefaultBufferSize = 1024 * 1024, // 1MB缓冲区MaxDepth = 64, // 限制嵌套深度PreferredObjectCreationHandling = JsonObjectCreationHandling.Replace,IgnoreReadOnlyProperties = true,IncludeFields = false
};
五、企业级应用实战
5.1 API响应包装器
public class ApiResponse<T>
{[JsonPropertyName("data")]public T Data { get; set; }[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]public string Error { get; set; }[JsonExtensionData]public Dictionary<string, object> Extensions { get; set; }
}// 使用示例
var response = new ApiResponse<Product> { Data = product };
var json = JsonSerializer.Serialize(response);
5.2 安全反序列化策略
var options = new JsonSerializerOptions
{// 限制最大Token数量MaxDepth = 32,// 限制最大字节数DefaultBufferSize = 1024 * 1024,// 自定义危险类型检测Converters = { new SafeConverter() }
};public class SafeConverter : JsonConverter<object>
{public override bool CanConvert(Type typeToConvert){if (typeToConvert == typeof(FileInfo))return false; // 禁止反序列化危险类型return true;}
}
六、调试与异常处理
6.1 常见异常处理
try
{var obj = JsonSerializer.Deserialize<T>(json);
}
catch (JsonException ex)
{// 定位错误位置Console.WriteLine($"Error at {ex.BytePositionInLine} line {ex.LineNumber}");Console.WriteLine($"Path: {ex.Path}");
}
catch (NotSupportedException ex)
{// 处理不支持的类型
}
6.2 JSON Path定位
using JsonDocument doc = JsonDocument.Parse(json);
var element = doc.RootElement.GetProperty("users")[0].GetProperty("address").GetProperty("city");
七、与Newtonsoft.Json对比迁移
7.1 主要差异对照表
特性 | Newtonsoft.Json | System.Text.Json |
---|---|---|
默认命名策略 | CamelCase | 保留原始名称 |
循环引用处理 | Preserve | Ignore/Preserve |
日期格式 | ISO 8601可配置 | 严格ISO 8601 |
异步支持 | 有限 | 完全支持 |
源码生成 | 不支持 | .NET 6+支持 |
7.2 兼容性封装器
public static class JsonHelper
{public static T DeserializeWithNewtonsoftCompatibility<T>(string json){var options = new JsonSerializerOptions{PropertyNameCaseInsensitive = true,NumberHandling = JsonNumberHandling.AllowReadingFromString,Converters = { new NewtonsoftCompatibilityConverter() }};return JsonSerializer.Deserialize<T>(json, options);}
}
八、未来趋势与扩展
8.1 JSON Schema验证
var schema = JsonSchema.FromType<Product>();
var results = schema.Validate(jsonElement);
if (!results.IsValid)
{foreach (var error in results){Console.WriteLine($"Validation error: {error.Path} - {error.Message}");}
}
8.2 动态JSON处理
JsonNode node = JsonNode.Parse(json)!;
node["users"][0]["name"] = "New Name";
string modifiedJson = node.ToJsonString();
九、性能优化检查清单
-
启用源码生成减少反射
-
重用JsonSerializerOptions实例
-
使用ArrayBufferWriter池化缓冲区
-
限制最大深度和缓冲区大小
-
避免不必要的属性转换
-
禁用未使用的功能(如注释处理)
十、最佳实践总结
-
配置管理:全局维护常用Options实例
-
安全优先:严格校验输入JSON结构
-
类型设计:
-
使用record类型不可变数据
-
明确[JsonInclude]和[JsonIgnore]
-
-
版本兼容:
-
使用[JsonExtensionData]保留未知属性
-
通过[JsonConstructor]控制反序列化构造
-