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

Posted

技术标签:

【中文标题】来自 ActionFilter 的 ModelState - ASP .NET Core 2.1 API【英文标题】:ModelState from ActionFilter - ASP .NET Core 2.1 API 【发布时间】:2018-12-15 12:57:21 【问题描述】:

我需要从“ModelState”中捕获错误以发送个性化消息。问题是如果 UserDTO 的属性具有“必需”属性,则永远不会执行过滤器。如果去掉就输入过滤器,但是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; 


【问题讨论】:

【参考方案1】:

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

验证错误会自动触发 HTTP 400 响应。

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

当 SuppressModelStateInvalidFilter 属性设置为 true 时,默认行为被禁用。在Startup.ConfigureServices中services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);之后添加如下代码

    services.Configure<ApiBehaviorOptions>(options =>     
options.SuppressModelStateInvalidFilter = true;  );

【讨论】:

我尝试使用最新的 ASPNET Core 2.1,但它似乎没有做任何事情。我正在尝试通过带有 OnPostAsync 的 2.1 Razor 页面上的“dotnet”在控制台中捕获无效模型消息。 有谁知道是否可以通过个人操作来防止这种情况发生?该功能确实很有帮助,但是当我需要在验证之前进行一些预处理时,我有一个操作。 有没有办法捕获异常?【参考方案2】:

在 ASP.NET Core 2.1 中,您还可以使用 ConfigureServices 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()
                )
            
        )
);

例如,此配置返回带有 error 字段的对象,其中结合了所有验证错误。 在这种情况下,不需要 ValidationAttribute,但您应该使用 [ApiController] 属性装饰您的控制器。

【讨论】:

以上是关于来自 ActionFilter 的 ModelState - ASP .NET Core 2.1 API的主要内容,如果未能解决你的问题,请参考以下文章

ActionFilter 的 order 属性,从最低到最高,反之亦然?

在 .net core c# 的 ExceptionFilter 中从 ActionFilter 中捕获异常

[Asp.Net Core]ActionFilter的特点

MVC-ActionFilter

为啥将自定义 WrappedRequest 与额外的类型参数和 ActionFilter 组合会导致类型丢失?

csharp 用于ASP.NET MVC的Ajax ActionFilter