缺少 属性 时如何强制 System.Text.Json 序列化程序抛出异常?
How to force System.Text.Json serializer throw exception when property is missing?
Json.NET 行为可以由属性定义:如果 json 有效载荷不包含必需的 属性.
,要么使用默认值,要么只抛出异常
然而 System.Text.Json
序列化程序静静地什么都不做。
有 class:
public sealed class Foo
{
[Required]
public int Prop {get;set;} = 10;
}
并反序列化空对象:
JsonSerializer.Deserialize<Foo>("{}");
我只是得到一个 Foo
和 Prop=10
的实例。
我在 JsonSerializerOptions
中找不到任何设置来强制它抛出异常。可能吗?
如果未收到目标类型的某个属性的值,System.Text.Json 不会引发异常。您需要实现自定义转换器。
System.Text.Json 不能完全替代 Json.NET。它是为速度而构建的,考虑到最少的分配,而不是功能的完整性。如果你想要验证,你可以
- 使用Json.NET
- 使用 Validator class
序列化后验证对象
- 创建自定义转换器
TheGeneral 展示了如何执行 #3。自定义验证器必须显式处理 所有 验证和 return 一些有意义的异常。如果只有一个 属性 需要检查,那么抛出一个 ArgumentNullException
就足够了。验证多个属性需要更复杂的东西,例如 ValidationException 来包含验证结果。
K。 Scott Allen 的文章 Manual Validation with Data Annotations 展示了如何执行 #2。
一个选项是使用 Validator.ValidateObject 来验证一个对象并得到一个包含所有失败验证的 ValidationException
:
try
{
var validationCtx=new ValidationContexgt(myFoo);
Validator.ValidateObject(myFoo,validationCtx);
}
catch(ValidatinException ex)
{
//Do something with the results.
}
如果无效对象很少见,这是可以的,因为抛出异常是昂贵的。也许更好的选择是使用 Validator.TryValidateObject :
var results = new List<ValidationResult>();
var validationCtx=new ValidationContexgt(myFoo);
if(Validator.TryValidateObject(myFoo,validationCtx,results))
{
//Use the object
}
else
{
//Do something with the failed results
}
您只需设置 MissingMemberHandling 即可,它会为您处理一切,但您需要安装 DevBetter.JsonExtensions
MissingMemberHandling.Ignore 和 MissingMemberHandling.Error
var deserializeOptions = new JsonSerializerOptions()
.SetMissingMemberHandling(MissingMemberHandling.Ignore);
var weatherForecast = JsonSerializer.Deserialize<WeatherForecast>(jsonString, deserializeOptions);
Json.NET 行为可以由属性定义:如果 json 有效载荷不包含必需的 属性.
,要么使用默认值,要么只抛出异常然而 System.Text.Json
序列化程序静静地什么都不做。
有 class:
public sealed class Foo
{
[Required]
public int Prop {get;set;} = 10;
}
并反序列化空对象:
JsonSerializer.Deserialize<Foo>("{}");
我只是得到一个 Foo
和 Prop=10
的实例。
我在 JsonSerializerOptions
中找不到任何设置来强制它抛出异常。可能吗?
System.Text.Json 不会引发异常。您需要实现自定义转换器。
System.Text.Json 不能完全替代 Json.NET。它是为速度而构建的,考虑到最少的分配,而不是功能的完整性。如果你想要验证,你可以
- 使用Json.NET
- 使用 Validator class 序列化后验证对象
- 创建自定义转换器
TheGeneral 展示了如何执行 #3。自定义验证器必须显式处理 所有 验证和 return 一些有意义的异常。如果只有一个 属性 需要检查,那么抛出一个 ArgumentNullException
就足够了。验证多个属性需要更复杂的东西,例如 ValidationException 来包含验证结果。
K。 Scott Allen 的文章 Manual Validation with Data Annotations 展示了如何执行 #2。
一个选项是使用 Validator.ValidateObject 来验证一个对象并得到一个包含所有失败验证的 ValidationException
:
try
{
var validationCtx=new ValidationContexgt(myFoo);
Validator.ValidateObject(myFoo,validationCtx);
}
catch(ValidatinException ex)
{
//Do something with the results.
}
如果无效对象很少见,这是可以的,因为抛出异常是昂贵的。也许更好的选择是使用 Validator.TryValidateObject :
var results = new List<ValidationResult>();
var validationCtx=new ValidationContexgt(myFoo);
if(Validator.TryValidateObject(myFoo,validationCtx,results))
{
//Use the object
}
else
{
//Do something with the failed results
}
您只需设置 MissingMemberHandling 即可,它会为您处理一切,但您需要安装 DevBetter.JsonExtensions MissingMemberHandling.Ignore 和 MissingMemberHandling.Error
var deserializeOptions = new JsonSerializerOptions()
.SetMissingMemberHandling(MissingMemberHandling.Ignore);
var weatherForecast = JsonSerializer.Deserialize<WeatherForecast>(jsonString, deserializeOptions);