ASP.NET Core 8 Web API:如何将全局异常信息纳入统一响应格式
实现全局异常返回统一格式的方案
方案一:基于自定义异常中间件(如果你的全局异常捕获用的是中间件)
如果当前全局异常处理是通过自定义中间件实现的,直接在中间件里构造ActionResponse<object>并返回就行,具体步骤如下:
- 修改异常中间件逻辑,捕获异常后生成增强错误信息,封装到统一响应对象中:
public class GlobalExceptionMiddleware { private readonly RequestDelegate _next; private readonly ILogger<GlobalExceptionMiddleware> _logger; public GlobalExceptionMiddleware(RequestDelegate next, ILogger<GlobalExceptionMiddleware> logger) { _next = next; _logger = logger; } public async Task InvokeAsync(HttpContext context) { try { await _next(context); } catch (Exception ex) { _logger.LogError(ex, "触发未处理异常"); // 生成增强错误信息,可根据环境、异常类型自定义内容 var errorMessage = GetEnhancedErrorMessage(ex); // 构造统一响应格式 var response = new ActionResponse<object> { WasSuccess = false, Message = errorMessage, Result = null }; // 设置响应参数 context.Response.ContentType = "application/json"; context.Response.StatusCode = StatusCodes.Status500InternalServerError; // 返回序列化后的响应 await context.Response.WriteAsJsonAsync(response); } } // 自定义增强错误信息生成逻辑 private string GetEnhancedErrorMessage(Exception ex) { // 开发环境返回详细堆栈,生产环境返回友好提示 var isDev = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == Environments.Development; return isDev ? $"错误详情:{ex.Message}\n堆栈信息:{ex.StackTrace}" : "服务器内部出错,请稍后重试"; } }
- 确保中间件在Program.cs中注册(如果之前没配置的话):
var builder = WebApplication.CreateBuilder(args); // ... 其他服务注册代码 var app = builder.Build(); // 异常中间件要放在最前面,才能捕获所有请求的异常 app.UseMiddleware<GlobalExceptionMiddleware>(); // ... 其他中间件(如UseRouting、UseAuthorization等) app.MapControllers(); app.Run();
方案二:基于异常过滤器(如果你的全局异常捕获用的是IExceptionFilter)
如果当前用的是过滤器实现全局异常捕获,修改过滤器逻辑即可:
- 自定义异常过滤器:
public class GlobalExceptionFilter : IExceptionFilter { private readonly ILogger<GlobalExceptionFilter> _logger; private readonly IWebHostEnvironment _env; public GlobalExceptionFilter(ILogger<GlobalExceptionFilter> logger, IWebHostEnvironment env) { _logger = logger; _env = env; } public void OnException(ExceptionContext context) { _logger.LogError(context.Exception, "触发未处理异常"); var errorMessage = GetEnhancedErrorMessage(context.Exception); // 构造统一响应对象 var response = new ActionResponse<object> { WasSuccess = false, Message = errorMessage, Result = null }; // 替换原异常响应,设置状态码 context.Result = new ObjectResult(response) { StatusCode = StatusCodes.Status500InternalServerError }; // 标记异常已处理,避免后续默认处理逻辑 context.ExceptionHandled = true; } private string GetEnhancedErrorMessage(Exception ex) { return _env.IsDevelopment() ? $"错误信息:{ex.Message}\n堆栈跟踪:{ex.StackTrace}" : "服务器内部错误,请联系管理员或稍后重试"; } }
- 在Program.cs中注册全局过滤器:
var builder = WebApplication.CreateBuilder(args); // 添加控制器服务并注册全局异常过滤器 builder.Services.AddControllers(options => { options.Filters.Add<GlobalExceptionFilter>(); }); // ... 其他服务注册代码 var app = builder.Build(); // ... 中间件配置 app.MapControllers(); app.Run();
额外优化:区分异常类型返回不同信息
如果有自定义业务异常,可以在生成错误信息时做区分:
private string GetEnhancedErrorMessage(Exception ex) { // 假设你有自定义的业务异常类BusinessException if (ex is BusinessException businessEx) { return businessEx.Message; // 直接返回业务友好提示 } return _env.IsDevelopment() ? $"错误详情:{ex.Message}\n堆栈:{ex.StackTrace}" : "服务器发生内部错误,请稍后重试"; }
不管用哪种方案,都是在异常被捕获后、响应返回给客户端前的时机,把增强错误信息填入ActionResponse<T>的Message属性,最终以统一格式返回给前端。
内容的提问来源于stack exchange,提问作者Robe79
相关产品推荐
相关产品推荐

