Pie*_*NAY 6 c# asp.net asp.net-core
我正在使用ASP.NET Core开发Web API,并且尝试实现自定义错误处理中间件,以便可以引发标准异常,可以使用适当的HTTP状态代码将其转换为JSON响应。
例如,如果我这样做:
throw new NotFoundApiException("The object was not found");
Run Code Online (Sandbox Code Playgroud)
我需要将其转换为:
StatusCode: 404
ContentType: application/json
ResponseBody: {"error": "The object was not found"}
Run Code Online (Sandbox Code Playgroud)
这是我的中间件:
public class ErrorHandlingMiddleware
{
private readonly RequestDelegate next;
public ErrorHandlingMiddleware(RequestDelegate next)
{
this.next = next;
}
public async Task Invoke(HttpContext context)
{
try {
await next(context);
} catch (ApiException ex) {
await HandleExceptionAsync(context, ex);
}
}
private static Task HandleExceptionAsync(HttpContext context, ApiException exception)
{
var result = JsonConvert.SerializeObject(new { error = exception.Message });
context.Response.ContentType = "application/json";
context.Response.StatusCode = exception.httpStatusCode;
return context.Response.WriteAsync(result);
}
}
Run Code Online (Sandbox Code Playgroud)
例外情况
public class ApiException : System.Exception
{
private int _httpStatusCode = (int)HttpStatusCode.InternalServerError;
public ApiException() { }
public ApiException(string message): base(message) { }
public int httpStatusCode {
get { return this._httpStatusCode; }
}
}
public class NotFoundApiException : ApiException
{
private int _httpStatusCode = (int)HttpStatusCode.BadRequest;
public NotFoundApiException() { }
public NotFoundApiException(string message): base(message) { }
}
Run Code Online (Sandbox Code Playgroud)
启动
public void Configure(/*...*/)
{
loggerFactory.AddConsole();
app.UseMiddleware<ErrorHandlingMiddleware>();
app.UseMvc();
}
Run Code Online (Sandbox Code Playgroud)
控制器动作
[HttpGet("object/{guid}")]
public WebMessage Get(Guid guid)
{
throw new NotFoundApiException(string.Format("The object {0} was not found", guid));
//...
Run Code Online (Sandbox Code Playgroud)
我可以看到请求进入了我注册的中间件,但是没有捕获到异常,只是像往常一样抛出了异常。
我怀疑存在竞争状况或类似情况,实际上我对它们的异步功能不是很了解。
有人知道为什么我的例外没有被抓住吗?
编辑通过继续执行VisualStudio,我可以看到预期的行为:我终于得到了响应。
似乎异常并未真正被中间件捕获,而是在以后以某种方式进行了处理。
您也可以尝试异常过滤器。
(当然,过滤器不像错误处理中间件那么灵活,在一般情况下更好,但是 - 至少对我来说 - 过滤器工作正常,没有任何问题)
这就是我正在使用的:
public class ExceptionGlobalFilter : ExceptionFilterAttribute
{
private readonly ILogger logger;
public ExceptionGlobalFilter(ILoggerFactory lf)
{
logger = lf.CreateLogger("ExceptionGlobalFilter");
}
public override void OnException(ExceptionContext context)
{
var customObject = new CustomObject(context.Exception);
//TODO: Add logs
if (context.Exception is BadRequestException)
{
context.Result = new BadRequestObjectResult(customObject);
}
else if (context.Exception is NotFoundException)
{
context.Result = new NotFoundObjectResult(customObject);
}
else
{
context.Result = new OkObjectResult(customObject);
}
base.OnException(context);
}
public override async Task OnExceptionAsync(ExceptionContext context)
{
await base.OnExceptionAsync(context);
return;
}
}
Run Code Online (Sandbox Code Playgroud)
Startup.cs:
services.AddMvc(config =>
{
config.Filters.Add(typeof(ExceptionGlobalFilter));
});
Run Code Online (Sandbox Code Playgroud)
更多信息:
| 归档时间: |
|
| 查看次数: |
3688 次 |
| 最近记录: |