【问题标题】:Customize automatic response on validation error自定义验证错误的自动响应
【发布时间】:2018-12-28 14:18:14
【问题描述】:

在 asp.net core 2.1 中,当发生验证错误时,ApiController 将自动响应 400 BadRequest。

如何更改/修改发送回客户端的响应(json-body)?是否有某种中间件?

我正在使用 FluentValidation 验证发送到我的控制器的参数,但我对收到的响应不满意。好像

{
    "Url": [
        "'Url' must not be empty.",
        "'Url' should not be empty."
    ]
}

我想更改响应,因为我们有一些附加到响应的默认值。所以它应该看起来像

{
    "code": 400,
    "request_id": "dfdfddf",
    "messages": [
        "'Url' must not be empty.",
        "'Url' should not be empty."
    ]
}

【问题讨论】:

    标签: c# validation asp.net-core


    【解决方案1】:

    ApiBehaviorOptions 类允许通过其InvalidModelStateResponseFactory 属性(类型为Func<ActionContext, IActionResult>)自定义ModelState 响应的生成。

    这是一个示例实现:

    apiBehaviorOptions.InvalidModelStateResponseFactory = actionContext => {
        return new BadRequestObjectResult(new {
            Code = 400,
            Request_Id = "dfdfddf",
            Messages = actionContext.ModelState.Values.SelectMany(x => x.Errors)
                .Select(x => x.ErrorMessage)
        });
    };
    

    传入的ActionContext 实例为活动请求提供ModelStateHttpContext 属性,其中包含我希望您可能需要的所有内容。我不确定你的 request_id 值来自哪里,所以我把它作为你的静态示例。

    要使用此实现,请在ConfigureServices 中配置ApiBehaviorOptions 实例:

    serviceCollection.Configure<ApiBehaviorOptions>(apiBehaviorOptions =>
        apiBehaviorOptions.InvalidModelStateResponseFactory = ...
    );
    

    【讨论】:

    • 只有在使用 PostConfigure 而不是 Configure 时才会生效(从 ASP.NET Core 3.1.8 开始)
    【解决方案2】:

    考虑创建自定义action filer,例如:

    public class CustomValidationResponseActionFilter : IActionFilter
    {
        public void OnActionExecuting(ActionExecutingContext context)
        {
            if (!context.ModelState.IsValid)
            {
                var errors = new List<string>();
    
                foreach (var modelState in context.ModelState.Values)
                {
                    foreach (var error in modelState.Errors)
                    {
                        errors.Add(error.ErrorMessage);
                    }
                }
    
                var responseObj = new
                {
                    code = 400,
                    request_id = "dfdfddf",
                    messages = errors
                };
    
                context.Result = new JsonResult(responseObj)
                {
                    StatusCode = 400
                };
            }
        }
    
        public void OnActionExecuted(ActionExecutedContext context)
        { }
    }
    

    您可以在ConfigureServices注册:

    services.AddMvc(options =>
    {
        options.Filters.Add(new CustomValidationResponseActionFilter());
    });
    

    【讨论】:

      猜你喜欢
      • 2016-05-07
      • 1970-01-01
      • 1970-01-01
      • 2015-06-16
      • 2015-11-24
      • 2017-09-24
      • 2018-06-17
      • 1970-01-01
      • 2019-02-03
      相关资源
      最近更新 更多