如何在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
相关产品推荐
相关产品推荐

