ASP.NET核心Web API异常处理 [英] ASP.NET Core Web API exception handling
问题描述
我开始使用ASP.NET核心使用常规的ASP.NET Web API多年后,我的新的REST API的项目。我没有看到处理ASP.NET中的核心Web API异常的好方法。我试图执行异常处理过滤器/属性:
I started using ASP.NET Core for my new REST API project after using regular ASP.NET Web API for many years. I don't see a good way to handle exceptions in ASP.NET Core Web API. I tried to implement exception handling filter/attribute:
public class ErrorHandlingFilter : ExceptionFilterAttribute
{
public override void OnException(ExceptionContext context)
{
if (context?.Exception != null)
{
HandleExceptionAsync(context);
context.ExceptionHandled = true;
}
}
private static void HandleExceptionAsync(ExceptionContext context)
{
var exception = context.Exception;
if (exception is MyNotFoundException)
SetExceptionResult(context, exception, HttpStatusCode.NotFound);
else if (exception is MyUnauthorizedException)
SetExceptionResult(context, exception, HttpStatusCode.Unauthorized);
else if (exception is MyException)
SetExceptionResult(context, exception, HttpStatusCode.BadRequest);
else
SetExceptionResult(context, exception, HttpStatusCode.InternalServerError);
}
private static void SetExceptionResult(ExceptionContext context, Exception exception, HttpStatusCode code)
{
context.Result = new JsonResult(new ApiResponse(exception))
{
StatusCode = (int)code
};
}
}
和这里是我的启动注册过滤器:
And here is my Startup filter registration:
services.AddMvc(options =>
{
options.Filters.Add(new AuthorizationFilter());
options.Filters.Add(new ErrorHandlingFilter());
});
我遇到的问题是,如果发生异常我 AuthorizationFilter
它不是由 ErrorHandlingFilter
处理。这似乎不可思议我,因为我认为执行顺序应该是这样的:
The issue I was having is that if exception occurred in my AuthorizationFilter
it's not being handled by ErrorHandlingFilter
. This seems weird for me because I think the execution order should be like that:
ExceptionHandlingFilter
{
AuthorizationFilter,
AnyOtherFilters ...
{
App
{
}
}
} // <-- handle all exceptions that occur in the scope.
如何让我的应用程序的工作这样?
How can make my app work like that?
推荐答案
经过多次实验,我可以说中间件是最适合在ASP中的异常处理.NET的核心Web API。它处理应用程序异常,以及发生在过滤器异常。
Full example of Exception Handling Middleware
After many experiments I can say that middleware is the best for exception handling in ASP.NET Core Web API. It handles application exceptions as well as exceptions that occur in filters.
请参阅异常处理的中间件类。无需实现接口或继承任何东西。唯一的规则:公共异步任务调用(...)
方法必须存在。 。如果需要,可以在构造函数中注入依赖
Please see exception handling middleware class. No need to implement interface or inherit anything. The only rule: public async Task Invoke(...)
method must be present. You can inject dependencies in constructor if needed.
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 (Exception ex)
{
await HandleExceptionAsync(context, ex);
}
}
private static async Task HandleExceptionAsync(HttpContext context, Exception exception)
{
if (exception == null) return;
var code = HttpStatusCode.InternalServerError;
if (exception is MyNotFoundException) code = HttpStatusCode.NotFound;
else if (exception is MyUnauthorizedException) code = HttpStatusCode.Unauthorized;
else if (exception is MyException) code = HttpStatusCode.BadRequest;
await WriteExceptionAsync(context, exception, code).ConfigureAwait(false);
}
private static async Task WriteExceptionAsync(HttpContext context, Exception exception, HttpStatusCode code)
{
var response = context.Response;
response.ContentType = "application/json";
response.StatusCode = (int)code;
await response.WriteAsync(JsonConvert.SerializeObject(new
{
error = new
{
message = exception.Message,
exception = exception.GetType().Name
}
})).ConfigureAwait(false);
}
}
我在MVC中之前把它注册启动
类:
app.UseMiddleware(typeof(ErrorHandlingMiddleware));
app.UseMvc();
如果异常发生时,网络API响应体看起来像:
If exception occur, Web API response body looks like that:
{
"error": {
"message": "Facebook authentication token is not valid.",
"exception": "MyUnauthorizedException"
}
}
这篇关于ASP.NET核心Web API异常处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!