8WebApi自定义模型验证

基于net5的WebApi模型验证

netCore跟之前的.net framework的模型验证下不太一样。在.net core下如果使用WebApi对于模型验证会自动使用ModelStateInvalidFilter 这个过滤器。而不是使用ModelState.IsValid来进行验证。如果想跟之前.net framework那样通过自定义的模型验证过滤器。有两种方法:
①自动替换默认模型验证。

②Net Core 禁用模型验证过滤器。
SuppressModelStateInvalidFilter = true时,会关闭默认模型验证过滤器。[ApiController] 默认自带有400模型验证,且优先级比较高,如果需要自定义模型验证,则需要先关闭默认的模型验证。

1. 用vs或者vscode创建一个net5的WebApi项目。创建一个ReturnMsg类,用来作为模型验证失败的结果消息类

这个类可以用于所有接口消息规范返回格式,但是这个类不是必须有的。

    public class ReturnMsg
    {        
        //返回的Code
        public string Code { get; set; }

        //消息
        public string Msg  { get; set; }

        //描述消息
        public string FullMsg  { get; set; }        
    }

2. 新建一个视图模型类Todo

    public class Todo
    {
        //ID
        public int Id { get; set; }        

        //名称
        [Required(ErrorMessage = "名称不能为空")]
        public string Name { get; set; }
    }

3. 进行模型验证

3.1 默认模型认证, 通过添加具体实现来替换默认模型验证(全局的)

使用模型验证要注入services.AddControllers();服务

           services.Configure<ApiBehaviorOptions>(options =>
            {
                string smsg="";
                options.InvalidModelStateResponseFactory = (context) =>
                {
                    foreach (var key in context.ModelState.Keys) {
                        var errors = context.ModelState[key].Errors;
                        if (errors.Count() > 0) {
                            smsg = errors[0].ErrorMessage;
                            break;
                        }
                    }

                    return  new JsonResult(new ReturnMsg() {Code = "500",Msg=smsg,FullMsg="参数验证未通过0"});
                };
            });

这样就可以进行全局模型验证了。如:
用PostMan工具进行接口测试:
image

注意:对应接口里一定要使用这个类,否则就不会进行模型验证
image


3.2 自定义的模型验证, 自定义的模型验证过滤器来实现模型验证

用自定义的模型过滤器进行模型验证要关闭默认模型验证过滤器
services.Configure<ApiBehaviorOptions>(options => options.SuppressModelStateInvalidFilter = true);

创建一个filter文件夹,里面创建一个action类型的过滤器

    public class MyActionFilter : IActionFilter
    {
        public void OnActionExecuted(ActionExecutedContext context)
        {
            
        }

        public void OnActionExecuting(ActionExecutingContext context)
        {
            

             if (!context.ModelState.IsValid)
            {
                //公共返回数据类
                ReturnMsg returnMsg = new ReturnMsg() { Code = "500" };
 
                //获取具体的错误消息
                foreach (var item in context.ModelState.Values)
                {
                    //遍历所有项目的中的所有错误信息
                    foreach (var err in item.Errors)
                    {
                        //消息拼接,用|隔开,前端根据容易解析
                        returnMsg.Msg += $"{err.ErrorMessage}"+",";
                    }
                }
                returnMsg.Msg = returnMsg.Msg.TrimEnd(',');

                returnMsg.FullMsg="参数验证未通过";

                context.Result = new JsonResult(returnMsg);
            }

        }
    }

用法1:全局使用模型验证

            services.AddControllers(opt=>{
                //添加过滤器
                opt.Filters.Add(typeof(MyActionFilter));
            });

用法2:局部使用,如控制器或者action

[TypeFilter(typeof(MyActionFilter))]

image

posted @ 2022-05-12 21:06  青仙  阅读(303)  评论(0编辑  收藏  举报