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

如何在Web API中重写HttpRequest验证错误消息并返回自定义异常对象?

解决方案

完全可以通过自定义错误处理中间件实现需求,中间件能捕获JSON解析错误和模型验证错误,并统一转换成你需要的TestException格式返回。以下是针对ASP.NET Core的具体实现步骤:

1. 定义TestException类

先确保自定义异常类符合需求:

public class TestException : Exception
{
    public int StatusCode { get; set; }
    public string Message { get; set; }

    public TestException(int statusCode, string message)
    {
        StatusCode = statusCode;
        Message = message;
    }
}

2. 编写自定义错误处理中间件

这个中间件会捕获两类关键错误:JSON格式解析错误(请求体格式非法)、模型验证错误(JSON格式合法但字段不符合校验规则),并转换成TestException格式返回:

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

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

    public async Task InvokeAsync(HttpContext context)
    {
        try
        {
            await _next(context);

            // 拦截默认的400模型验证响应
            if (context.Response.StatusCode == StatusCodes.Status400BadRequest && !context.Response.HasStarted)
            {
                var modelState = context.Features.Get<Microsoft.AspNetCore.Mvc.ModelBinding.IModelStateDictionary>();
                if (modelState != null && !modelState.IsValid)
                {
                    // 拼接所有验证错误信息
                    var errorMsg = string.Join("; ", modelState.Values
                        .SelectMany(v => v.Errors)
                        .Select(e => string.IsNullOrEmpty(e.ErrorMessage) ? e.Exception.Message : e.ErrorMessage));
                    var testException = new TestException(StatusCodes.Status400BadRequest, errorMsg);
                    await HandleExceptionResponse(context, testException);
                }
            }
        }
        catch (Exception ex)
        {
            // 捕获JSON解析异常(System.Text.Json.JsonException)
            if (ex is JsonException jsonEx)
            {
                var testException = new TestException(StatusCodes.Status400BadRequest, $"JSON格式错误: {jsonEx.Message}");
                await HandleExceptionResponse(context, testException);
            }
            else
            {
                // 处理其他未捕获异常
                _logger.LogError(ex, "服务器未处理异常");
                var testException = new TestException(StatusCodes.Status500InternalServerError, "服务器内部错误");
                await HandleExceptionResponse(context, testException);
            }
        }
    }

    // 统一生成错误响应
    private async Task HandleExceptionResponse(HttpContext context, TestException exception)
    {
        context.Response.ContentType = "application/json";
        context.Response.StatusCode = exception.StatusCode;
        await context.Response.WriteAsJsonAsync(new 
        { 
            StatusCode = exception.StatusCode, 
            Message = exception.Message 
        });
    }
}

3. 注册中间件并禁用默认验证响应

在Program.cs中注册中间件(需放在其他业务中间件之前,确保优先捕获错误),同时禁用框架默认的模型验证响应,避免冲突:

var builder = WebApplication.CreateBuilder(args);

// 添加控制器服务,禁用默认模型验证响应
builder.Services.AddControllers(options =>
{
    options.SuppressModelStateInvalidFilter = true;
});

var app = builder.Build();

// 注册自定义错误处理中间件
app.UseMiddleware<CustomErrorHandlingMiddleware>();

app.UseAuthorization();

app.MapControllers();

app.Run();

关键说明

  • 中间件的优势:能在请求进入控制器之前捕获JSON解析错误,这是过滤器无法做到的;
  • 错误信息拼接:针对模型验证错误,会把所有字段的错误信息拼接成字符串传入TestException,你可以根据需求调整格式(比如保留原错误数组);
  • 扩展性:如果需要处理其他异常类型,只需在catch块中添加对应判断即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 03:43:31