.NET 8 Preview 2 对 DataAnnotation 的增强
Intro
在 .NET 8 Preview 2 中对于 DataAnnotation 增加了一些新的特性,使用 DataAnnotation 可以进行更多的验证了
New features
RequiredAttribute.DisallowAllDefaultValues
在 RequiredAttribute
中新增了一个 DisallowAllDefaultValue
,我们可以禁用一些默认值,尤其是对值类型的属性而言
比如说我们可能会用到的 Guid
,我们 customerId 会用 Guid
有些查询 customerId 是必填的,但是如果不填的话,会默认使用 Guid.Empty
这就导致我们不得不在代码里加一些检查,类似于下面这样:
if (request.CustomerId == Guid.Empty)
return BadRequest();
在有了这个之后我们就可以清理掉这样的逻辑了,只需要设置 [Required(DisallowAllDefaultValues = true)]
即可
RangeAttribute exclusive bounds
针对 RangeAttribute
新增了 MinimumIsExclusive
和 MaximumIsExclusive
,之前的行为 min 和 max 都是允许的值,这使得我们可以根据需要选择是否要包含 min/max,这对于一些浮点数会比较实用
LengthAttribute
新增加了一个 LengthAttribute
来集合 string 或者集合的长度,类似于 Range 可以指定最小值和最大值
AllowedValuesAttribute && DeniedValuesAttribute
新增加了 AllowedValuesAttribute
/DeniedValuesAttribute
用来指定允许的值和非法的值
Base64StringAttribute
新增加了 Base64StringAttribute
来验证输入是一个合法的 base64 字符串,有一些上传图片/文件使用 base64 或者使用 base64 encode 的字段可以使用这个来比较方便的验证
Sample
来看一个完整的示例:
先定义我们要用来验证的 model
file sealed class Request
{
[Required(DisallowAllDefaultValues = true)]
public Guid CustomerId { get; set; }
[AllowedValues("Dev", "Test", "Production")]
public string RequestType { get; set; }
[DeniedValues("Admin", "Administrator")]
public string UserName { get; set; }
[Range(0d, 1d, MaximumIsExclusive = true, MinimumIsExclusive = false)]
public double LuckyRate { get; set; }
[Required]
[Base64String]
public string Image { get; set; }
[Length(1, 10)]
public string[] Items { get; set; }
}
验证代码如下:
var request = new Request()
{
CustomerId = Guid.Empty,
RequestType = "Admin",
UserName = "Admin",
LuckyRate = 1,
Image = "123",
Items = Array.Empty<string>()
};
var validationContext = new ValidationContext(request);
var validationResults = new List<ValidationResult>();
if (Validator.TryValidateObject(request, validationContext, validationResults, true))
{
Console.WriteLine("Object valid");
}
else
{
Console.WriteLine(validationResults.ToJson());
}
输出结果如下:
More
大家注意的话,最后的 error message 是有些风格不一致的,提了一个 issue,大家感兴趣的话可以瞅瞅哈
https://github.com/dotnet/runtime/issues/83642
References
https://github.com/dotnet/runtime/pull/82311
https://devblogs.microsoft.com/dotnet/announcing-dotnet-8-preview-2/
https://github.com/WeihanLi/SamplesInPractice/blob/master/net8sample/Net8Sample/DataAnnotationSample.cs
https://github.com/dotnet/runtime/issues/83642