如何在 UseExceptionHandler 中访问 ModelState

Posted

技术标签:

【中文标题】如何在 UseExceptionHandler 中访问 ModelState【英文标题】:How to access ModelState in UseExceptionHandler 【发布时间】:2022-01-23 01:10:02 【问题描述】:

我的域服务会抛出自定义 DomainServiceValidationException 以进行业务验证。我想全局捕获异常并在 ModelState 中返回。我目前的工作解决方案是使用ExceptionFilterAttribute

public class ExceptionHandlerAttribute : ExceptionFilterAttribute

    private readonly ILogger<ExceptionHandlerAttribute> _logger;

    public ExceptionHandlerAttribute(ILogger<ExceptionHandlerAttribute> logger)
    
        _logger = logger;
    
    public override void OnException(ExceptionContext context)
    
        
        if (context == null || context.ExceptionHandled)
        
            return;
        

       if(context.Exception is DomainServiceValidationException)  
       
          context.ModelState.AddModelError("Errors", context.Exception.Message);
          context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
          context.Result = new BadRequestObjectResult(context.ModelState);
       
       else
       
            handle exception
       
    

想知道UseExceptionHandler中间件有没有办法访问ModelState

public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime appLifetime)
            
        app.UseExceptionHandler(new ExceptionHandlerOptions()
        
            ExceptionHandler = async (context) =>
            
                var ex = context.Features.Get<IExceptionHandlerFeature>().Error;

               // how to access to ModelState here                        
                
            
        );                
                

【问题讨论】:

【参考方案1】:

缩短答案:

不,您不能在 UseExceptionHandler 中间件中访问 ModelState。

解释:

首先你需要知道ModelState只有在Model Binding之后才可用

然后模型绑定在Action Filters 之前和Resource Filters 之后调用(参见图 1)。但是Middleware 在过滤器之前调用(参见图 2)。

图一:

图2:

参考:

How Filters work

结论:

也就是说,你无法在UseExceptionHandler中间件中获取ModelState

解决方法:

您只能将ModelState 自动存储在过滤器(操作过滤器或异常过滤器或结果过滤器)中,然后您可以在中间件中使用它。

app.UseExceptionHandler(new ExceptionHandlerOptions()

    ExceptionHandler = async (context) =>
    
        var ex = context.Features.Get<IExceptionHandlerFeature>().Error;
        // how to access to ModelState here                        
        var data = context.Features.Get<ModelStateFeature>()?.ModelState;
    
);

参考:

How to store ModelState automatically

【讨论】:

以上是关于如何在 UseExceptionHandler 中访问 ModelState的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ASP.NET Core 中为 gRPC 服务添加全局异常处理 ?

将开发人员异常页面显示为 IActionResult

如何在图像中找到明亮区域(以及如何在图像中找到阴影区域)

在QGIS中如何添加天地图的WMTS

如何在异步任务中调用意图?或者如何在 onPostExecute 中开始新的活动?

如何在Allegro中测量距离