编程语言
首页 > 编程语言> > Ultimate ASP.NET CORE 6.0 Web API --- 读书笔记(13)

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,如果模型验证不通过,缺点就是,不允许返回我们自定义的状态码和信息,所以在前面已经在主项目中配置禁止了这种行为

[ValidateNever]
[Compare]
[EmailAddress]
[Phone]
[Range]
[RegularExpression]
[Required]
[StringLength]

有时候默认提供的Attributes对一些场景支持不够好,所以我们可以自定义Attributes,两种方法:

例子:

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,那么问题来了,当PATCHremove这个字段的时候,这个字段的值会变成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