必需的属性
从 .NET 7 开始,可以标记某些属性,用于指示其必须存在于 JSON 有效负载中,反序列化才能成功。 如果其中一个或多个所需的属性不存在,JsonSerializer.Deserialize 方法将引发一个 JsonException。
有三种方法可以标记 JSON 反序列化所需的属性或字段:
- 通过添加 C# 11 中新增的必需修饰符。
- 通过借助 .NET 7 中新增的 JsonRequiredAttribute 对其进行注释。
- 通过修改 .NET 7 中新增的协定模型的 JsonPropertyInfo.IsRequired 属性。
从序列化程序的角度来看,这两个分界是等效的,并且均映射到同一元数据片段,即 JsonPropertyInfo.IsRequired。 大多数情况下,只需使用内置的 C# 关键字即可。 但是,在以下情况中,应改用 JsonRequiredAttribute:
- 如果你使用的是 C# 以外的编程语言或 C# 的低级版本。
- 如果只想将要求应用于 JSON 反序列化。
- 如果在源生成模式下使用
System.Text.Json
序列化。 在这种情况下,如果使用required
修饰符,代码不会编译,因为源生成是在编译时发生的。
以下代码片段显示使用 required
关键字修改过的属性示例。 JSON 有效负载中必须有此属性,反序列化才能成功。
using System.Text.Json;
// The following line throws a JsonException at run time.
Console.WriteLine(JsonSerializer.Deserialize<Person>("""{"Age": 42}"""));
public class Person
{
public required string Name { get; set; }
public int Age { get; set; }
}
也可使用 JsonRequiredAttribute:
using System.Text.Json;
// The following line throws a JsonException at run time.
Console.WriteLine(JsonSerializer.Deserialize<Person>("""{"Age": 42}"""));
public class Person
{
[JsonRequired]
public string Name { get; set; }
public int Age { get; set; }
}
还可以使用 JsonPropertyInfo.IsRequired 属性,通过协定模型来控制是否需要某个属性:
var options = new JsonSerializerOptions
{
TypeInfoResolver = new DefaultJsonTypeInfoResolver
{
Modifiers =
{
static typeInfo =>
{
if (typeInfo.Kind != JsonTypeInfoKind.Object)
return;
foreach (JsonPropertyInfo propertyInfo in typeInfo.Properties)
{
// Strip IsRequired constraint from every property.
propertyInfo.IsRequired = false;
}
}
}
}
};
// Deserialization now succeeds even though the Name property isn't in the JSON payload.
JsonSerializer.Deserialize<Person>("""{"Age": 42}""", options);
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈