aspnet core 全局模型验证,统一api响应

上手就来

        新建一个模型验证过滤器,其中ApiResp是自定义的统一响应类。

public class VldFilter:IActionFilter
    {
        /// <summary>
        /// 执行到action时
        /// </summary>
        /// <param name="context"></param>
        public void OnActionExecuting(ActionExecutingContext context)
        {
            if (!context.ModelState.IsValid)
            {
                StringBuilder errTxt = new StringBuilder();
                foreach (var item in context.ModelState.Values)
                {
                    foreach (var error in item.Errors)
                    {
                        errTxt.Append(error.ErrorMessage + "|");
                    }
                }

                // api响应报文,多封装几个构造方法,这里使用模型验证失败的响应码和模型校验信息
                ApiResp result = new ApiResp(ApiRespCode.F400000, errTxt.ToString().Substring(0, errTxt.Length - 1));
                context.Result = new JsonResult(result);
            }
        }

        public void OnActionExecuted(ActionExecutedContext context)
        {
        }

    }

        ApiResp大概长这样,响应code使用自定义的枚举,从000000到999999,有足够的空间满足不同类型的响应码。

public class ApiResp
    {
        public bool Success;

        public string SysTime;

        public string Code;

        public string Message;

        public object Data;
    }

 

        在startup设置Mvc options

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options =>
    {
        options.MaxModelValidationErrors = 5;
        options.Filters.Add<VldFilter>();
    }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

        写一个SayHello接口测试一下,然而返回数据并不是ApiResp类型,仍然是默认的返回类型。貌似并没有执行自定义过滤器。

        将Api控制器改为MVC控制器,取消[ApiController]特性,并将继承类由ControllerBase改为Controller。

  查看一下ControllerControllerBase的差别,Controller有继承ControllerBaseIActionFilterControllerBase是一个基类,没有任何继承类。

 

正确姿势

        在startup设置ApiBehaviorOptions,启用自定义模型验证。

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options =>
    {
        options.MaxModelValidationErrors = 5;
        options.Filters.Add<VldFilter>();
    }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

    services.Configure<ApiBehaviorOptions>(options =>
    {
        options.SuppressModelStateInvalidFilter = true; // 使用自定义模型验证
    }
}

        得到正确的响应类

 

另一种正确姿势

        直接在ApiBehaviorOptions中处理模型验证,并封装响应报文,不需要额外的VldFilter。但是这种方式只适用于WebApi项目,如果是MVC项目,还是使用自定义模型验证比较好。而且WebApi项目也支持自定义模型验证,不过需要设置ApiBehaviorOptions启用自定义模型验证。

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options =>
    {
        options.MaxModelValidationErrors = 10;
        //options.Filters.Add<VldFilter>();
    }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    // 实现统一模型验证,无须VldFilter。
    services.Configure<ApiBehaviorOptions>(options =>
    {
//options.SuppressModelStateInvalidFilter = true; // 使用自定义模型验证 options.InvalidModelStateResponseFactory = (context) => { StringBuilder errTxt = new StringBuilder(); foreach (var item in context.ModelState.Values) { foreach (var error in item.Errors) { errTxt.Append(error.ErrorMessage + "|"); } } ApiResp result = new ApiResp(ApiRespCode.F400000,errTxt.ToString().Substring(0,errTxt.Length-1)); return new JsonResult(result); }; }); }

 

posted @ 2019-10-13 23:29  原来是李  阅读(1033)  评论(0编辑  收藏  举报