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

如何在ASP.NET中间件中捕获System.Text.Json序列化错误

解决ASP.NET Core JSON序列化异常捕获问题

你的try/catch块无法触发,核心原因是:Ok(apiEntity)仅创建了一个OkObjectResult对象,JSON序列化操作并非在Action方法执行时同步完成,而是后续ASP.NET Core管道的响应处理阶段才会执行,因此异常不会被当前Action内的catch捕获。

以下是几种可行的解决方案:

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

通过中间件捕获整个请求管道中发生的序列化异常,这是最通用的方式:

public class JsonSerializationExceptionMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<JsonSerializationExceptionMiddleware> _logger;

    public JsonSerializationExceptionMiddleware(RequestDelegate next, ILogger<JsonSerializationExceptionMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (ArgumentException ex) when (ex.Message.Contains("JSON value of length") && ex.Message.Contains("too large"))
        {
            _logger.LogError(ex, "JSON序列化遇到过大值错误");
            context.Response.StatusCode = StatusCodes.Status400BadRequest;
            context.Response.ContentType = "application/json";
            await context.Response.WriteAsJsonAsync(new ApiError { Message = "数据过大,无法完成序列化" });
        }
    }
}

注册中间件(在Program.cs中,需放在路由和端点中间件之前):

app.UseMiddleware<JsonSerializationExceptionMiddleware>();
app.UseRouting();
app.UseEndpoints(endpoints => { endpoints.MapControllers(); });

2. 使用Action结果过滤器

针对控制器Action的结果执行阶段捕获异常,更聚焦于API响应场景:

public class JsonSerializationFilter : IAsyncResultFilter
{
    private readonly ILogger<JsonSerializationFilter> _logger;

    public JsonSerializationFilter(ILogger<JsonSerializationFilter> logger)
    {
        _logger = logger;
    }

    public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
    {
        try
        {
            await next();
        }
        catch (ArgumentException ex) when (ex.Message.Contains("JSON value of length") && ex.Message.Contains("too large"))
        {
            _logger.LogError(ex, "JSON序列化过大值错误");
            context.Result = new BadRequestObjectResult(new ApiError { Message = "数据超出序列化大小限制" });
        }
    }
}

注册过滤器(Program.cs中):

builder.Services.AddControllers(options =>
{
    options.Filters.Add<JsonSerializationFilter>();
});

3. 调整JSON序列化大小限制(可选)

如果业务允许返回超大对象,可以通过配置放宽序列化限制,从根源避免异常:

builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        // 调整JSON序列化的最大深度(默认64)
        options.JsonSerializerOptions.MaxDepth = 128;
    });

// 同时调整HTTP请求/响应的整体大小限制
builder.Services.Configure<Microsoft.AspNetCore.Http.Features.FormOptions>(options =>
{
    options.MultipartBodyLengthLimit = 800 * 1024 * 1024; // 示例:800MB
});

额外建议

如果业务场景确实需要处理超大对象,优先考虑:

  • 分页返回数据,避免一次性序列化全量数据
  • 启用响应压缩(如Gzip),减少传输体积
  • 使用流式响应,逐步序列化并返回数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 19:22:54