在 ASP.NET Core Web API 中使用异常筛选器捕获和统一处理异常
前言
在 ASP.NET Core Web API 中,异常筛选器(Exception Filter)是一种用于处理发生在 Web API 控制器或管道中的异常的机制。
异常筛选器可以捕获和处理应用程序中发生的异常,当系统中出现未经处理的异常的时候,异常筛选器就会执行,我们可以在异常筛选器中对异常进行处理,例如记录日志、返回自定义错误信息等。
需要注意的是,只有 ASP.NET Core 线程中的未处理异常才会被异常筛选器处理。
本文主要通过一个实例来讲述在 ASP.NET Core Web API 中如何使用异常筛选器。
Step By Step 步骤
-
创建一个ASP.NET Core webapi 项目
-
编写自定义的异常筛选器 MyExceptionFilter,实现 IAsyncExceptionFilter 接口(注意其中的注释)
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; public class MyExceptionFilter : IAsyncExceptionFilter { private readonly ILogger<MyExceptionFilter> logger; private readonly IHostEnvironment env; // 注入 ILogger 和 IHostEnvironment // IHostEnvironment 用于判断环境类型 public MyExceptionFilter( ILogger<MyExceptionFilter> logger, IHostEnvironment env) { this.logger = logger; this.env = env; } public Task OnExceptionAsync(ExceptionContext context) { Exception exception = context.Exception; logger.LogError(exception, "UnhandledException occured"); string message; if (env.IsDevelopment()) { // 如果是开发环境,打印所有的异常堆栈信息 message = exception.ToString(); } else { // 否则只打印简单信息 message = "程序中出现未处理异常"; } // 设置响应报文的内容 ObjectResult result = new ObjectResult(new { code = 500, message = message }); result.StatusCode = 500; context.Result = result; // 设置context.ExceptionHandled的值为true,让ASP.NET Core不再执行默认的异常响应逻辑 context.ExceptionHandled = true; return Task.CompletedTask; } }
-
打开 Program.cs,设置全局的筛选器(注意其中的注释)
using Microsoft.AspNetCore.Mvc; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); // 注册自定义异常过滤器服务 // MvcOptions是ASP.NET Core项目的主要配置对象 // 用于向Filters注册全局的筛选器 builder.Services.Configure<MvcOptions>(opt => { opt.Filters.Add<MyExceptionFilter>(); }); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
-
打开控制器,模拟错误进行测试
using Microsoft.AspNetCore.Mvc; namespace 异常筛选器.Controllers { [ApiController] [Route("[controller]")] public class WeatherForecastController : ControllerBase { private readonly ILogger<WeatherForecastController> _logger; public WeatherForecastController(ILogger<WeatherForecastController> logger) { _logger = logger; } [HttpGet(Name = "GetWeatherForecast")] public string Get() { throw new Exception("xxx"); } } }
我是老杨,一个执着于编程乐趣、至今奋斗在一线的 10年+ 资深研发老鸟,是软件项目管理师,也是快乐的程序猿,持续免费分享全栈实用编程技巧、项目管理经验和职场成长心得!欢迎关注老杨的公众号(名称:代码掌控者),和你共同探索代码世界的奥秘!