如何在ASP.Net Core Web API中实现全局异常处理

异常是应用程序中发生的运行时错误。 如果处理不当,将终止正在运行的程序。 我们如何防止这种情况发生? 我们可以使用全局异常处理程序来确保捕获所有未处理的异常。

为了在ASP.Net Core Web API中实现全局异常处理,我们可以利用内置的中间件UseExceptionHandler。 中间件是插入到请求处理管道中的软件组件,用于处理请求和响应。

[.Net路线图: .Net Standard 2.1中可以期待新功能 | .Net Framework或.Net Core? 了解何时使用哪个 | 通过InfoWorld的App Dev Report新闻通讯了解编程方面的热门话题。 ]

在构建ASP.Net Core应用程序时,我们可以利用各种中间件组件来自定义请求和响应的处理,甚至检查,路由或修改流经管道的请求和响应消息。

在本文中,我将展示如何使用UseExceptionHandler中间件在ASP.Net Core Web API中全局处理异常。

在Visual Studio 2017中创建ASP.Net Core Web API项目

首先,让我们创建一个ASP.Net Core Web API项目。 如果您的系统已启动并运行Visual Studio 2017,请按照下面概述的步骤创建一个ASP.Net Core Web API项目。

  1. 启动Visual Studio 2017 IDE。
  2. 单击文件>新建>项目。
  3. 从显示的模板列表中选择“ ASP.Net Core Web应用程序(.Net Core)”。
  4. 指定项目的名称。
  5. 单击确定保存项目。
  6. 选择“ .Net Core”作为运行时,然后从窗口顶部的下拉列表中选择ASP.Net Core 2.1(或更高版本)。
  7. 选择“ API”作为项目模板。
  8. 确保未选中“启用Docker支持”和“配置HTTPS”复选框。 我们将不会使用这些功能。
  9. 确保选择“无身份验证”,因为我们也不会使用身份验证。
  10. 单击确定。

这将创建一个新的ASP.Net Core Web API项目。 在以下各节中,我们将使用该项目来实现全局异常处理。

aspnet核心全局异常处理1 IDG

在Visual Studio 2017中创建ASP.Net Core Web API应用程序。

在ASP.Net Core中使用UseExceptionHandler中间件

ASP.Net Core请求处理管道包括一系列中间件组件。 该管道反过来包含一系列的请求委托,它们被一个又一个地调用。 当传入的请求流经管道中的每个中间件组件时,这些组件中的每一个都可以处理请求,也可以将请求传递给管道中的下一个组件。

以下代码段说明了如何配置UseExceptionHandler中间件,以在发生异常时将用户重定向到错误页面。

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseMvc();
        }

如果您想捕获异常对象的详细信息(例如,堆栈跟踪等),则可以使用以下代码。

app.UseExceptionHandler(
                options =>
                {
                    options.Run(
                        async context =>
                        {
                            context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                            context.Response.ContentType = "text/html";
                            var exceptionObject = context.Features.Get<IExceptionHandlerFeature>();
                            if (null != exceptionObject)
                            {                              
                                var errorMessage = $"<b>Error: {exceptionObject.Error.Message}</b>{exceptionObject.Error.StackTrace}";
                                await context.Response.WriteAsync(errorMessage).ConfigureAwait(false);
                            }
                        });
                }
            );

接下来,使用以下代码更新ValuesController中的默认Get操作方法。

  [HttpGet]
  public ActionResult<IEnumerable<string>> Get()
   {
       throw new Exception("An error occurred...");
   }

运行该应用程序,您将看到在Web浏览器中显示的堆栈跟踪,如下图所示。

aspnet核心全局异常处理2 IDG

Web浏览器中显示的异常跟踪。

创建一个自定义中间件来处理ASP.Net Core Web API中的异常

您还可以编写自己的中间件来处理异常。 这是一个示例,说明了典型的自定义中间件类。 编写自己的自定义中间件来处理异常可以提供更大的灵活性。 您可以添加堆栈跟踪,异常类型名称,错误代码或其他任何您想包含在错误消息中的内容。

这是一个示例,说明了典型的自定义中间件类。

public class CustomExceptionMiddleware
{
    private readonly RequestDelegate _next;
    public CustomExceptionMiddleware(RequestDelegate next)
    {
        _next = next;
    }
    public async Task Invoke(HttpContext context)
    {
        try
        {
            await _next.Invoke(context);
        }
        catch (Exception ex)
        {
            //Write code to handle exception here
        }
    }
}

请注意,请求委托将传递给任何中间件。 然后,中间件要么对其进行处理,要么将其传递给链中的下一个中间件。 如果请求失败,则将引发异常,并在catch块中调用HandleExceptionAsync方法。

现在,使用以下代码更新Invoke方法。

public async Task Invoke(HttpContext context)
        {
            try
            {
                await _next.Invoke(context);
            }
            catch (Exception ex)
            {
                await HandleExceptionAsync(context,
                 ex).ConfigureAwait(false);
            }
        }

这是HandleExceptionAsync方法的代码。

private static Task HandleExceptionAsync(HttpContext context, Exception exception)
        {
            context.Response.ContentType = "application/json";
            int statusCode = (int)HttpStatusCode.InternalServerError;
            var result = JsonConvert.SerializeObject(new {StatusCode = statusCode, ErrorMessage = exception.Message });
            context.Response.ContentType = "application/json";
            context.Response.StatusCode = statusCode;
            return context.Response.WriteAsync(result);
        }

这是CustomExceptionMiddleware类的完整代码清单,供您参考。

public class CustomExceptionMiddleware
    {
        private readonly RequestDelegate _next;
        public CustomExceptionMiddleware(RequestDelegate next)
        {
            _next = next;
        }
        public async Task Invoke(HttpContext context)
        {
            try
            {
                await _next.Invoke(context);
            }
            catch (Exception ex)
            {
                await HandleExceptionAsync(context, ex).ConfigureAwait(false);
            }
        }
private static Task HandleExceptionAsync(HttpContext context, Exception exception)
        {
            context.Response.ContentType = "application/json";
            int statusCode = (int)HttpStatusCode.InternalServerError;
            var result = JsonConvert.SerializeObject(new {StatusCode = statusCode,
               ErrorMessage = exception.Message });
            context.Response.ContentType = "application/json";
            context.Response.StatusCode = statusCode;
            return context.Response.WriteAsync(result);
        }
    }

仅需两个步骤。 接下来,创建一个名为ExceptionMiddlewareExtensions的静态类,并包含以下代码。

public static class ExceptionMiddlewareExtensions
    {
        public static void UseCustomExceptionMiddleware(this IApplicationBuilder app)
        {
            app.UseMiddleware<CustomExceptionMiddleware>();
        }
    }

最后,您现在可以在Startup类的Configure方法中打开自定义中间件,如下面的代码片段所示。

public void Configure(IApplicationBuilder app,
IHostingEnvironment env)
        {
            app.UseCustomExceptionMiddleware();
            app.UseMvc();
        }

运行应用程序时,异常输出将显示在Web浏览器中,如下图所示。

aspnet核心全局异常处理3 IDG

定制异常处理中间件的实际应用。

在每个应用程序中,异常处理都是一个贯穿各领域的问题。 幸运的是,我们可以利用ASP.Net Core中的全局异常处理来确保捕获到每个异常,并且无需在每次编写新的控制器或控制器方法时都编写额外的样板代码。 使用全局异常处理,我们只需要在一个地方一次为我们的应用编写异常处理代码。 最好编写自己的自定义中间件来全局处理异常。

From: https://www.infoworld.com/article/3322503/how-to-implement-global-exception-handling-in-aspnet-core-web-api.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值