.NET Core 中 System.Text.Json 元数据读取器取消转义属性名的重大变更解析
docs This repository contains .NET Documentation. 项目地址: https://gitcode.com/gh_mirrors/docs2/docs
引言
在.NET 9中,System.Text.Json库对元数据属性名称的处理方式进行了重要调整。这一变更主要影响了JSON文档在引用保留、多态性和元数据属性验证方面的行为。本文将深入解析这一变更的技术细节、影响范围以及开发者需要注意的事项。
变更背景
JSON序列化是现代应用程序开发中的基础功能,System.Text.Json作为.NET平台的高性能JSON处理库,其行为变更直接影响着众多应用程序的兼容性。元数据属性(如以"$"开头的属性)在JSON处理中具有特殊意义,正确处理这些属性对于保证数据一致性至关重要。
变更详情
旧版本行为(.NET 8及之前)
在.NET 8及更早版本中,System.Text.Json不会对元数据属性名称进行取消转义处理。这导致以下两个问题:
- 验证绕过:通过Unicode转义可以绕过元数据属性验证
- 多态性问题:在往返序列化时,需要转义的元数据属性名称会导致类型识别失败
// 旧版本中,以下代码会成功执行
JsonSerializer.Deserialize<MyPoco>("""{"\u0024invalid" : 42 }""", options);
// 但直接使用$符号的属性会抛出异常
JsonSerializer.Deserialize<MyPoco>("""{"$invalid" : 42 }""", options);
新版本行为(.NET 9及之后)
.NET 9中,System.Text.Json现在会对元数据属性名称进行取消转义处理。这一变更带来了以下改进:
- 严格的验证:所有元数据属性名称都会经过统一验证
- 正确的多态性处理:转义后的属性名称能够正确识别类型
// 新版本中,以下代码会抛出异常
JsonSerializer.Deserialize<MyPoco>("""{"\u0024invalid" : 42 }""", options);
// 异常信息
// System.Text.Json.JsonException: Properties that start with '$' are not allowed in types that support metadata.
实际影响示例
考虑以下多态类型序列化场景:
string json = JsonSerializer.Serialize<Base>(new Derived());
Console.WriteLine(json); // 输出: {"categor\u00EDa":"derived"}
Console.WriteLine(JsonSerializer.Deserialize<Base>(json) is Derived); // 旧版本: False, 新版本: True
[JsonPolymorphic(TypeDiscriminatorPropertyName = "categoría")]
[JsonDerivedType(typeof(Derived), "derived")]
public record Base;
public record Derived : Base;
在.NET 9中,由于属性名称被正确取消转义,类型识别现在能够正常工作。
变更类型
此变更属于行为变更,可能影响现有应用程序的兼容性。
开发者应对建议
- 避免使用转义绕过验证:不再依赖转义字符来使用特殊属性名
- 检查现有代码:审查代码中是否使用了转义的元数据属性名
- 选择合规的属性名:确保属性名不冲突于元数据属性命名规则
受影响API范围
此变更主要影响以下API:
- System.Text.Json命名空间下的相关功能
- JsonSerializer.Deserialize方法及其重载
结论
System.Text.Json在.NET 9中对元数据属性名称处理的改进,提高了库的健壮性和一致性。开发者应当了解这一变更,及时调整代码以适应新的行为规范,确保应用程序的稳定运行。这一改进也体现了.NET团队对JSON处理细节的持续优化,为开发者提供了更可靠的序列化/反序列化体验。
docs This repository contains .NET Documentation. 项目地址: https://gitcode.com/gh_mirrors/docs2/docs
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考