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

能否为Kestrel编写自定义异常处理器?ASP.NET Core技术问询

ASP.NET Core 捕获特定异常并返回自定义响应的正确方式

你可以通过两种符合ASP.NET Core架构设计的方式实现需求,既不用手动在每个端点写try/catch包装器,也能保留框架自带的JSON序列化等功能:

一、全局异常处理中间件(推荐全局统一处理)

通过配置UseExceptionHandler中间件,全局捕获特定异常并返回自定义响应,适用于需要对所有端点统一处理同类型异常的场景:

步骤1:定义自定义异常

public class SomeCustomException : Exception
{
    public SomeCustomException(string message = "请求冲突") : base(message)
    {
    }
}

步骤2:配置全局异常处理中间件

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

var app = WebApplication.Create();
app.Urls.Add("http://localhost:3001");

// 配置全局异常处理逻辑
app.UseExceptionHandler(errorApp =>
{
    errorApp.Run(async context =>
    {
        var exceptionFeature = context.Features.Get<Microsoft.AspNetCore.Diagnostics.IExceptionHandlerPathFeature>();
        var exception = exceptionFeature?.Error;

        if (exception is SomeCustomException customEx)
        {
            // 设置409冲突状态码
            context.Response.StatusCode = StatusCodes.Status409Conflict;
            context.Response.ContentType = "application/json";

            // 构造响应对象,框架会自动完成JSON序列化
            var errorResponse = new
            {
                StatusCode = context.Response.StatusCode,
                Message = customEx.Message,
                RequestPath = exceptionFeature.Path
            };

            await context.Response.WriteAsync(JsonSerializer.Serialize(errorResponse));
        }
        else
        {
            // 其他异常返回默认500响应
            context.Response.StatusCode = StatusCodes.Status500InternalServerError;
            context.Response.ContentType = "application/json";
            await context.Response.WriteAsync(JsonSerializer.Serialize(new
            {
                StatusCode = 500,
                Message = "服务器内部错误"
            }));
        }
    });
});

app.MapGet("/error", ThrowAnError);

string ThrowAnError()
{
    throw new SomeCustomException();
}

app.Run();

二、端点过滤器(针对特定端点处理)

如果只需要对部分端点处理特定异常,可以使用端点过滤器,精准控制范围:

步骤1:定义异常处理过滤器

public class CustomExceptionFilter : IEndpointFilter
{
    public async ValueTask<object?> InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next)
    {
        try
        {
            return await next(context);
        }
        catch (SomeCustomException ex)
        {
            // 利用框架内置的Results对象返回响应,自动处理序列化
            return Results.Conflict(new
            {
                Message = ex.Message,
                StatusCode = StatusCodes.Status409Conflict
            });
        }
    }
}

步骤2:为目标端点添加过滤器

var app = WebApplication.Create();
app.Urls.Add("http://localhost:3001");

// 仅给/error端点添加异常处理过滤器
app.MapGet("/error", ThrowAnError)
   .AddEndpointFilter<CustomExceptionFilter>();

string ThrowAnError()
{
    throw new SomeCustomException();
}

app.Run();

这两种方式都遵循ASP.NET Core的架构设计,保留了框架的所有原生功能(如JSON序列化、内容协商等),避免了手动try/catch带来的代码冗余和功能缺失。

内容的提问来源于stack exchange,提问作者billpg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 09:52:53