Ultimate ASP.NET CORE 6.0 Web API --- 读书笔记(13)
作者:互联网
13 Validation
本文内容来自书籍: Marinko Spasojevic - Ultimate ASP.NET Core Web API - From Zero To Six-Figure Backend Developer (2nd edition)
只需要对输入验证,而不是输出,以及在验证参数不正确的时候,如何返回一个合适的响应给客户端
13.1 ModelState,Rerun Validation,and Build-in Attributes
使用数据注释特性,会引入一个概念:ModelState
这是一个字典,包含着模型的状态和模型绑定验证器
注意:模型的验证是发生在模型绑定之后,如果验证失败,那么会报错,在请求到达action
之前,模型绑定和验证就做好了,然后在action
中,可以使用ModelState.IsValid
可以看到模型的验证是否通过
一般,在Web API
中,我们不会使用ModelState.IsValid
来验证结果,因为在前面的章节中提到,
[ApiController]
特性,已经帮我们对验证结果已经做了包装,默认会返回400 – BadRequest
,如果模型验证不通过,缺点就是,不允许返回我们自定义的状态码和信息,所以在前面已经在主项目中配置禁止了这种行为
- 常用的
Build-in Attributes
[ValidateNever]
[Compare]
[EmailAddress]
[Phone]
[Range]
[RegularExpression]
[Required]
[StringLength]
有时候默认提供的Attributes
对一些场景支持不够好,所以我们可以自定义Attributes,两种方法:
- 继承ValidationAttribute
- 实现IValidatableObject
例子:
public class ScienceBookAttribute : ValidationAttribute
{
public BookGenre Genre { get; set; }
public string Error => $"The genre of the book must be {BookGenre.Science}";
public ScienceBookAttribute(BookGenre genre)
{
Genre= genre;
}
protected override ValidationResult? IsValid(object? value, ValidationContext
validationContext)
{
var book = (Book)validationContext.ObjectInstance;
if (!book.Genre.Equals(Genre.ToString()))
return new ValidationResult(Error);
return ValidationResult.Success;
}
}
public class Book : IValidatableObject
{
public int Id { get; set; }
[Required]
public string? Name { get; set; }
[Range(10, int.MaxValue)]
public int Price { get; set; }
public string? Genre { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext
validationContext)
{
var errorMessage = $"The genre of the book must be {BookGenre.Science}";
if (!Genre.Equals(BookGenre.Science.ToString()))
yield return new ValidationResult(errorMessage, new[] { nameof(Genre) });
}
}
13.5 Validation for PATCH Requests
在验证PATCH
方法的时候,基本和其他的方法一样,但是有一点需要注意的是,在验证remove
的时候,会将基本数据类型还原为默认的值,比如
[Range(18, int.MaxValue, ErrorMessage = "Age is required and it can't be lower than 18")]
public int Age { get; init; }
这个的验证规则是,这个值不允许小于18,那么问题来了,当PATCH
是remove
这个字段的时候,这个字段的值会变成0,但是在最开始的验证中,是没有问题的,但是当数据存入数据库的时候,是不应该的,因为会修改为0,所以需要第二次验证,比如
// 第一次验证,PATCH的验证是发生在这个方法的
patchDoc.ApplyTo(result.employeeToPatch, ModelState);
// 需要第二次验证,这时候的0会触发验证规则
TryValidateModel(result.employeeToPatch);
标签:ModelState,CORE,13,set,验证,读书笔记,Genre,get,public 来源: https://www.cnblogs.com/huangwenhao1024/p/16383187.html