来自 ActionFilter 的 ModelState - ASP .NET Core 2.1 API

ModelState from ActionFilter - ASP .NET Core 2.1 API

我需要捕获来自 "ModelState" 的错误以发送个性化消息。问题在于,如果 UserDTO 的 属性 具有属性 "Required",则永远不会执行过滤器。如果去掉,进入filter,但是modelState是有效的

[HttpPost]
[ModelState]
public IActionResult Post([FromBody] UserDTO currentUser)
{
    /*if (!ModelState.IsValid)
    {
        return BadRequest();
    }*/
    return Ok();
}

public class ModelStateAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext currentContext)
    {
        if (!currentContext.ModelState.IsValid)
        {
            currentContext.Result = new ContentResult
            {
                Content = "Modelstate not valid",
                StatusCode = 400
            };
        }
        else
        {
            base.OnActionExecuting(currentContext);
        }
    }
}

public class UserDTO
{
    [Required]
    public string ID { get; set; }

    public string Name { get; set; }

}

您的问题是由一项新功能引起的 Automatic HTTP 400 responses

Validation errors automatically trigger an HTTP 400 response.

因此,如果您想自定义验证错误,则需要禁用此功能。

当 SuppressModelStateInvalidFilter 属性 设置为 true 时,默认行为被禁用。在services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

之后的Startup.ConfigureServices中添加如下代码
    services.Configure<ApiBehaviorOptions>(options => {    
options.SuppressModelStateInvalidFilter = true;  });

在 ASP.NET Core 2.1 中,您还可以在 ConfigureServices at Startup.cs:

中使用 InvalidModelStateResponseFactory 参数更改验证错误响应
services.Configure<ApiBehaviorOptions>(options =>
    options.InvalidModelStateResponseFactory = actionContext =>
        new BadRequestObjectResult(
            new
            {
                error = string.Join(
                    Environment.NewLine,
                    actionContext.ModelState.Values.SelectMany(v => v.Errors.Select(x => x.ErrorMessage)).ToArray()
                )
            }
        )
);

例如,此配置 returns 对象与 error 字段合并了所有验证错误。 在这种情况下,不需要 ValidationAttribute,但你应该用 [ApiController] 属性装饰你的控制器。