模型状态错误过滤器

时间:2018-05-24 08:50:16

标签: c# asp.net-core filter asp.net-core-mvc

在我的DTO对象上,我有几个属性来检查它的有效性

当验证失败时,我会收到这样的身体反应

{
    "TransactionId": [
    "Max length is 20"
    ],
    "AdditionalInfo": [
    "Additional Info has to be no longer than 30 chars"
    ]
}

但我需要将所有错误统一为“错误”键。 像这样的东西

{
    "Error": [
    "Max length is 20",
    "Additional Info has to be no longer than 30 chars"
    ]
} 

我写了一个特殊的过滤器并在Startup.cs中注册了它

public class ModelStateErrorHandlingFilter : IAsyncActionFilter
{
    public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {

        if (!context.ModelState.IsValid)
        {
            context.ModelState.SetModelValue("Errors", new ValueProviderResult(new StringValues(context.ModelState.ToString())));
            context.Result = new BadRequestObjectResult(context.ModelState);
        }
        else
        {
            await next().ConfigureAwait(false);
        }
    }
}

但没有任何改变。我也试图改变密钥,但它有私有的setter

1 个答案:

答案 0 :(得分:2)

您需要提供自己的自定义IActionResult或构建所需的对象模型并将其传递给适当的ObjectResult

public class ModelStateErrorHandlingFilter : IAsyncActionFilter {
    public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) {
        if (!context.ModelState.IsValid) {
            var model = new {
                Error = context.ModelState
                    .SelectMany(keyValuePair => keyValuePair.Value.Errors)
                    .Select(modelError => modelError.ErrorMessage)
                    .ToArray()
            };
            context.Result = new BadRequestObjectResult (model);
        } else {
            await next().ConfigureAwait(false);
        }
    }
}

设置context.Result会使请求短路,并将您的自定义响应传递给所需内容。