详解.NET Model ValidationAttribute的使用

1,253 阅读3分钟

!!! 本文已参与「新人创作礼」活动,一起开启掘金创作之路。更多干货文章,可以访问 菜鸟厚非

一、简介

ValidationAttribute 验证特性一般用来验证数据的格式,范围,是否必填等,我们通过它的子类特性 Range、Required 等特性可以轻松实现对数据的验证。但是对于一些特殊需要的特性,系统自带的特性局限性很大,我们也可以自定义扩展需要的特性。

二、ASP.NET 应用

ValidationAttribute 应用在 ASP.NET MVC 中是常用得,用于对 HTPP Request 参数字段得校验,不通过得会返回 400 提示给调用方。接下通过一个简单例子进行说明一下,例子使用得是 .NET Web API 。

2.1 Model

首先定义一个 request model 添加一些字段,如 Name 打上 Required、MinLength、MaxLength 这样的标记进行限制

public class PersonalRequest
{
    public int Id { get; set; }
    
    [Required]
    [MinLength(2), MaxLength(20)]
    public string Name { get; set; }

    public string Sex { get; set; }

    [Required]
    [MinLength(2), MaxLength(20)]
    public string Address { get; set; }
}

2.2 Controller

定义完 request model 后,创建一个 API ,将上一步定义的 request model 作为参数。此时在 request model 字段上打的 Required、MinLength、MaxLength 标记,是没有任何作用的。

[HttpPost]
[Route("WebAPIApply")]
public IActionResult WebAPIApply(PersonalRequest request)
{
    return Ok();
}

2.4 Filter

为了让 request model 字段上打的 Required、MinLength、MaxLength 标记生效, MVC 中需要使用到 Filter 。代码如下

public class ModelValidateFilter : IAsyncActionFilter
{
    public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        if (!context.ModelState.IsValid)
        {
            var allErrors = context.ModelState.Values.SelectMany(v => v.Errors);
            var message = string.Join(" | ", allErrors.Select(e => e.ErrorMessage));
            context.Result = new JsonResult(new { results = allErrors });
        }
        await next();
    }
}

2.5 注册

Filter 创建完成后,需要注册一下,这里我们使用全局模式。如下

builder.Services.AddMvc(opt =>
{
    opt.Filters.Add(new ModelValidateFilter());
});

在这里插入图片描述

2.6 验证

程序创建完成后,调用 API 验证一下,如下对 Name 分别赋值了 D Da。 可以看到当是 D 的时候,字段长度为 1 ,filter 对 request model 进行了正确的校验 在这里插入图片描述

在这里插入图片描述

三、直接验证实例

直接验证实例,是指可以对定义 model 的实例,自定义代码对齐进行校验,这种使用起来相对灵活,但也不经常使用。接下通过一个简单例子进行说明一下

3.1 Model

首先定义一个 model 添加一些字段,如 Name 打上 Required、MinLength、MaxLength 这样的标记进行限制

public class Personal
{
    [Required]
    public int ID { get; set; }
    
    [Required]
    [MinLength(2), MaxLength(5)]
    public string Name { get; set; }
}

3.2 Validation Code

校验代码如下,先对定义的 model 进行了实例化,然后使用 Validator.TryValidateObject 方法进行校验,实际工作中需要自己进行一些封装。关键代码如下:

Personal personal = new Personal();
// personal.Name = "D";
ValidationContext validationContext = new ValidationContext(personal);
List<ValidationResult> results = new List<ValidationResult>();
bool isValid = Validator.TryValidateObject(personal, validationContext, results, true);

在这里插入图片描述

3.3 验证

代码写完后,调用 API 验证一下。首先直接调用,应为代码里面没有对 Personal 实例赋值,正确的进行了 Required 标记的校验 在这里插入图片描述 可以修改下代码 personal.Name = "Da",然后启动程序,调用一下 API 可以看到校验是通过的 在这里插入图片描述 可以修改下代码 personal.Name = "D",然后启动程序,调用一下 API 可以看到校验是不通过的,因为长度为 1 没有满足 MinLength(2) 在这里插入图片描述

四、自定义 ValidationAttribute

除了可以使用 Microsoft 提供的 ValidationAttribute ,我们还可以使用自定义的 ValidationAttribute ,微软这方面提供了可扩展性。自定义的 ValidationAttribute 只需继承 ValidationAttribute,重写 IsValid 、FormatErrorMessage 即可。使用方面与 Microsoft 提供的 ValidationAttribute 使用一模一样。如下代码

public class CanToIntAttribute : ValidationAttribute
{
    /// <summary>
    /// IsValid 为 false 时,提示得 error 信息
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public override string FormatErrorMessage(string name)
    {
        return $"{name} need to int";
    }

    /// <summary>
    /// 验证当前字段得结果
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public override bool IsValid(object value)
    {
        int num = 0;
        return int.TryParse(Convert.ToString(value), out num);
    }
}
public class PersonalRequest
{
    public int Id { get; set; }

    public string Name { get; set; }

    [CanToInt]
    public string Sex { get; set; }

    [Required]
    [MinLength(2), MaxLength(20)]
    public string Address { get; set; }
}

在这里插入图片描述

五、源码

download.csdn.net/download/we…