ASP.Net Core 模型验证统一处理

判断验证状态时一般会在Action里判断ModelState.IsValid是否为true

public IActionResult Create([FromBody]CreateOrderDto dto)
{
        if(ModelState.IsValid)
        {
            //TODO:...
        }
}

如果每个需要验证的Action里面都写这个判断岂不是太麻烦,我们是否可以在进入所有的Action之前都进行验证,如果错误,就直接返回错误信息,不去执行Action了,当然时可以的。我们可以利用MVC的ActionFilter即Action过滤器,在执行Action之前统一判断处理。

这里通过ActionFilterAttribute过滤器来实现这个功能

首先创建应该过滤器ValidateModelFilter

/// <summary>
/// 统一模型验证返回
/// </summary>
public class ValidateModelFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (!context.ModelState.IsValid)
        {
            var result = context.ModelState.Keys
                    .SelectMany(key => context.ModelState[key].Errors.Select(x => new ValidationError(key, x.ErrorMessage)))
                    .ToList();
            var res = new { code = "10001", message = "实体类验证错误", data = result };
            context.Result = new ObjectResult(res);
        }
    }
}

public class ValidationError
{
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public string Field { get; }
    public string Message { get; }
    public ValidationError(string field, string message)
    {
        Field = field != string.Empty ? field : null;
        Message = message;
    }
}

然后将这个过滤器应用到全局设置,当然也可以局部应用

//全局注册异常过滤器
services.AddControllersWithViews(option => {
    option.Filters.Add<ValidateModelFilter>();
});

最后不要忘记要禁用.NetCore默认的验证处理器

services.Configure<ApiBehaviorOptions>(options => options.SuppressModelStateInvalidFilter = true);