如何在 UseExceptionHandler 中访问 ModelState
How to access ModelState in UseExceptionHandler
我有域服务,可以为业务验证抛出自定义 DomainServiceValidationException
。我想在 ModelState 中全局捕获异常和 return。我目前的工作解决方案是使用 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
}
});
}
}
缩短答案:
不,您不能在 UseExceptionHandler 中间件中访问 ModelState。
解释:
首先你要知道ModelState只有在Model Binding后才可用。
然后模型绑定在 Action Filters
之前和 Resource Filters
之后调用(见图 1)。但是 Middleware
在过滤器之前调用(见图 2)。
图一:
图二:
参考:
结论:
也就是说,你无法获取UseExceptionHandler
中间件中的ModelState
。
解决方法:
您只能将 ModelState
自动存储在过滤器(Action Filters 或 Exception Filters 或 Result Filters)中,然后您可以在中间件中使用它。
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
我有域服务,可以为业务验证抛出自定义 DomainServiceValidationException
。我想在 ModelState 中全局捕获异常和 return。我目前的工作解决方案是使用 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
}
});
}
}
缩短答案:
不,您不能在 UseExceptionHandler 中间件中访问 ModelState。
解释:
首先你要知道ModelState只有在Model Binding后才可用。
然后模型绑定在 Action Filters
之前和 Resource Filters
之后调用(见图 1)。但是 Middleware
在过滤器之前调用(见图 2)。
图一:
图二:
参考:
结论:
也就是说,你无法获取UseExceptionHandler
中间件中的ModelState
。
解决方法:
您只能将 ModelState
自动存储在过滤器(Action Filters 或 Exception Filters 或 Result Filters)中,然后您可以在中间件中使用它。
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