You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 8 Web API:如何将全局异常信息纳入统一响应格式

实现全局异常返回统一格式的方案

方案一:基于自定义异常中间件(如果你的全局异常捕获用的是中间件)

如果当前全局异常处理是通过自定义中间件实现的,直接在中间件里构造ActionResponse<object>并返回就行,具体步骤如下:

  1. 修改异常中间件逻辑,捕获异常后生成增强错误信息,封装到统一响应对象中:
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}" 
            : "服务器内部出错,请稍后重试";
    }
}
  1. 确保中间件在Program.cs中注册(如果之前没配置的话):
var builder = WebApplication.CreateBuilder(args);

// ... 其他服务注册代码

var app = builder.Build();

// 异常中间件要放在最前面,才能捕获所有请求的异常
app.UseMiddleware<GlobalExceptionMiddleware>();

// ... 其他中间件(如UseRouting、UseAuthorization等)

app.MapControllers();

app.Run();

方案二:基于异常过滤器(如果你的全局异常捕获用的是IExceptionFilter)

如果当前用的是过滤器实现全局异常捕获,修改过滤器逻辑即可:

  1. 自定义异常过滤器:
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}"
            : "服务器内部错误,请联系管理员或稍后重试";
    }
}
  1. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 11:27:17