ASP.NET核心Web API异常处理 [英] ASP.NET Core Web API exception handling

查看:530
本文介绍了ASP.NET核心Web API异常处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆