【问题标题】:How to access ModelState in UseExceptionHandler如何在 UseExceptionHandler 中访问 ModelState
【发布时间】: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                        
                
            }
        });                
    }            
}

【问题讨论】:

    标签: asp.net-core .net-core asp.net-core-mvc asp.net-core-3.1


    【解决方案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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-30
      • 1970-01-01
      • 2020-12-31
      • 2019-02-21
      • 2010-11-06
      • 1970-01-01
      • 1970-01-01
      • 2021-06-20
      相关资源
      最近更新 更多