导读:本期聚焦于小伙伴创作的《C#怎么实现WebAPI异常处理 C#如何在ASP.NET Core中全局捕获异常返回统一错误信息》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C#怎么实现WebAPI异常处理 C#如何在ASP.NET Core中全局捕获异常返回统一错误信息》有用,将其分享出去将是对创作者最好的鼓励。

在ASP.NET Core中开发WebAPI时,统一的异常处理是保障接口规范性的重要环节。如果缺少全局异常处理,当接口抛出未捕获的异常时,框架会返回默认的500错误页面或者混乱的JSON数据,前端难以解析,也不利于问题排查。通过C#实现全局异常捕获,可以让所有异常都返回固定格式的错误信息,提升API的易用性和可维护性。

C#怎么实现WebAPI异常处理 C#如何在ASP.NET Core中全局捕获异常返回统一错误信息

统一错误返回模型定义

首先我们需要定义一个统一的错误返回实体,确保所有异常返回的信息结构一致,方便前端统一处理。

public class ApiErrorResult
{
    /// <summary>
    /// 错误码,0表示成功,非0表示失败
    /// </summary>
    public int Code { get; set; }

    /// <summary>
    /// 错误提示信息
    /// </summary>
    public string Message { get; set; }

    /// <summary>
    /// 接口返回的时间戳
    /// </summary>
    public long Timestamp { get; set; }

    public ApiErrorResult(int code, string message)
    {
        Code = code;
        Message = message;
        Timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
    }

    /// <summary>
    /// 快速创建服务器内部错误返回实例
    /// </summary>
    public static ApiErrorResult InternalServerError(string message = "服务器内部错误")
    {
        return new ApiErrorResult(500, message);
    }
}

方式一:使用中间件实现全局异常处理

中间件可以拦截所有进入管道的请求,适合处理全局范围的异常,包括中间件阶段和控制器阶段抛出的异常。

1. 自定义异常处理中间件

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using System;
using System.Text.Json;
using System.Threading.Tasks;

public class GlobalExceptionMiddleware
{
    private readonly RequestDelegate _next;

    public GlobalExceptionMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        try
        {
            // 执行下一个中间件
            await _next(context);
        }
        catch (Exception ex)
        {
            // 捕获异常,返回统一错误格式
            await HandleExceptionAsync(context, ex);
        }
    }

    private static async Task HandleExceptionAsync(HttpContext context, Exception exception)
    {
        context.Response.ContentType = "application/json";
        // 默认返回500状态码
        context.Response.StatusCode = StatusCodes.Status500InternalServerError;

        // 可以针对不同类型的异常设置不同的状态码和错误码
        var errorResult = ApiErrorResult.InternalServerError(exception.Message);
        // 如果是自定义的业务异常,可以调整返回信息
        if (exception is BusinessException businessEx)
        {
            context.Response.StatusCode = StatusCodes.Status400BadRequest;
            errorResult = new ApiErrorResult(businessEx.ErrorCode, businessEx.Message);
        }

        var jsonOptions = new JsonSerializerOptions
        {
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase
        };
        var json = JsonSerializer.Serialize(errorResult, jsonOptions);
        await context.Response.WriteAsync(json);
    }
}

/// <summary>
/// 自定义业务异常类
/// </summary>
public class BusinessException : Exception
{
    public int ErrorCode { get; }

    public BusinessException(int errorCode, string message) : base(message)
    {
        ErrorCode = errorCode;
    }
}

2. 注册中间件

Program.cs中添加中间件注册,注意中间件要放在路由和控制器中间件之前,才能捕获到后续流程的异常。

var builder = WebApplication.CreateBuilder(args);

// 添加控制器服务
builder.Services.AddControllers();

var app = builder.Build();

// 注册全局异常处理中间件,放在最前面
app.UseMiddleware<GlobalExceptionMiddleware>();

// 其他中间件
app.UseRouting();
app.MapControllers();

app.Run();

方式二:使用异常过滤器实现异常处理

异常过滤器只针对控制器中的动作方法抛出的异常生效,适合处理MVC/WebAPI场景下的异常,粒度更细。

1. 自定义异常过滤器

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Text.Json;

public class GlobalExceptionFilter : IExceptionFilter
{
    public void OnException(ExceptionContext context)
    {
        // 标记异常已处理
        context.ExceptionHandled = true;
        context.HttpContext.Response.ContentType = "application/json";
        context.HttpContext.Response.StatusCode = StatusCodes.Status500InternalServerError;

        var errorResult = ApiErrorResult.InternalServerError(context.Exception.Message);
        // 处理自定义业务异常
        if (context.Exception is BusinessException businessEx)
        {
            context.HttpContext.Response.StatusCode = StatusCodes.Status400BadRequest;
            errorResult = new ApiErrorResult(businessEx.ErrorCode, businessEx.Message);
        }

        var jsonOptions = new JsonSerializerOptions
        {
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase
        };
        var json = JsonSerializer.Serialize(errorResult, jsonOptions);
        context.Result = new ContentResult
        {
            Content = json,
            ContentType = "application/json",
            StatusCode = context.HttpContext.Response.StatusCode
        };
    }
}

2. 注册异常过滤器

Program.cs中把过滤器添加到控制器配置中。

var builder = WebApplication.CreateBuilder(args);

// 添加控制器并配置全局异常过滤器
builder.Services.AddControllers(options =>
{
    options.Filters.Add<GlobalExceptionFilter>();
});

var app = builder.Build();

app.UseRouting();
app.MapControllers();

app.Run();

两种方式的对比与选择

对比项中间件方式异常过滤器方式
作用范围整个请求管道,包括中间件和控制器仅控制器中的动作方法
适用场景需要捕获所有请求的异常,包括静态文件、中间件抛出的异常仅需要处理控制器相关的异常,粒度更细
优先级更高,先注册先执行较低,属于MVC管道的一部分

实际开发中可以根据需求选择,也可以两种方式结合使用,中间件处理全局兜底异常,过滤器处理控制器特定的异常逻辑。

测试验证

我们可以编写一个测试的控制器方法,主动抛出异常验证处理效果。

using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/[controller]")]
public class TestController : ControllerBase
{
    [HttpGet("normal")]
    public IActionResult NormalRequest()
    {
        return Ok(new { code = 0, message = "请求成功" });
    }

    [HttpGet("exception")]
    public IActionResult ThrowException()
    {
        // 主动抛出业务异常
        throw new BusinessException(1001, "参数校验失败");
    }

    [HttpGet("system-error")]
    public IActionResult SystemError()
    {
        // 抛出系统异常
        throw new NullReferenceException("对象未实例化");
    }
}

调用/api/test/exception接口会返回400状态码和自定义错误格式,调用/api/test/system-error会返回500状态码和统一错误信息,符合预期效果。

C#ASP.NET_CoreWebAPI全局异常处理统一返回格式修改时间:2026-06-14 02:15:18

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。