System.Text.Json 元数据阅读器现在可取消元数据属性名称的转义

System.Text.Json 库已更新为取消转义元数据属性名称。 此更改会影响在引用保留、多态性和元数据属性验证上下文中解释 JSON 文档的方式。

已引入的版本

.NET 9

以前的行为

以前,System.Text.Json 未取消转义元数据属性名称。 这将导致接受无效的属性名称,从而绕过元数据属性验证。

例如,以下代码将在第一次调用中成功,但在第二次调用中引发异常:

JsonSerializerOptions options = new() { ReferenceHandler = ReferenceHandler.Preserve };
JsonSerializer.Deserialize<MyPoco>("""{"\u0024invalid" : 42 }""", options);
JsonSerializer.Deserialize<MyPoco>("""{"$invalid" : 42 }""", options);

record MyPoco;

在对名称需要转义的元数据属性进行往返处理时,未正确转义的行为可能导致多态性问题,如下所示:

string json = JsonSerializer.Serialize<Base>(new Derived());
Console.WriteLine(json); // {"categor\u00EDa":"derived"}
Console.WriteLine(JsonSerializer.Deserialize<Base>(json) is Derived); // False

[JsonPolymorphic(TypeDiscriminatorPropertyName = "categoría")]
[JsonDerivedType(typeof(Derived), "derived")]
public record Base;
public record Derived : Base;

新行为

System.Text.Json 现在取消转义元数据属性名称。 此新行为意味着多态反序列化示例中的行 Console.WriteLine(JsonSerializer.Deserialize<Base>(json) is Derived); 现在返回 true,并且无效的属性名称正确地无法反序列化,导致以下异常:

Unhandled exception. System.Text.Json.JsonException: Properties that start with '$' are not allowed in types that support metadata.

破坏性变更的类型

此更改为行为更改

更改原因

此更改通过确保元数据属性名称正确取消转义,从而防止绕过元数据属性验证,从而提高了正确性和可靠性。 有关更多详细信息,请参阅 报告的问题

避免使用转义绕过元数据属性验证。 而是选择与元数据属性不冲突的属性名称。

受影响的 API