.NET 6 Web API如何自定义模型绑定失败时的400错误响应?
.NET 6 Web API 自定义模型绑定错误响应
当提交的JSON无法绑定到MyRequest模型时,默认的400错误响应格式可以通过以下两种常用方式自定义:
方法一:自定义ProblemDetailsFactory(全局覆盖)
默认的错误响应由ProblemDetailsFactory生成,通过自定义该工厂可以全局修改所有场景下的ProblemDetails格式,包括模型验证错误。
1. 创建自定义工厂类
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Mvc.ModelBinding; using System.Diagnostics; using Microsoft.Extensions.Options; public class CustomProblemDetailsFactory : DefaultProblemDetailsFactory { public CustomProblemDetailsFactory(IOptions<ApiBehaviorOptions> options, ILoggerFactory loggerFactory) : base(options, loggerFactory) { } public override ProblemDetails CreateValidationProblemDetails( HttpContext httpContext, ModelStateDictionary modelStateDictionary, int statusCode = StatusCodes.Status400BadRequest, string? title = null, string? type = null, string? detail = null, string? instance = null) { var problemDetails = base.CreateValidationProblemDetails( httpContext, modelStateDictionary, statusCode, title, type, detail, instance); // 替换默认字段值 problemDetails.Type = "VALIDATION_FAILED"; problemDetails.Title = "数据验证失败"; problemDetails.Detail = "提交的请求数据格式不符合要求,请检查后重试"; // 格式化错误字段,移除$.前缀,更友好 var formattedErrors = new Dictionary<string, string[]>(); foreach (var key in modelStateDictionary.Keys) { var friendlyFieldName = key.Replace("$.", string.Empty); formattedErrors[friendlyFieldName] = modelStateDictionary[key].Errors .Select(error => error.ErrorMessage) .ToArray(); } problemDetails.Extensions["errors"] = formattedErrors; // 移除默认traceId,添加自定义字段 problemDetails.Extensions.Remove("traceId"); problemDetails.Extensions.Add("timestamp", DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ")); problemDetails.Extensions.Add("requestId", Activity.Current?.Id ?? httpContext.TraceIdentifier); return problemDetails; } }
2. 注册自定义工厂
在Program.cs中替换默认的工厂实现:
builder.Services.AddSingleton<ProblemDetailsFactory, CustomProblemDetailsFactory>();
方法二:配置ApiBehaviorOptions(针对性处理模型验证)
通过ApiBehaviorOptions的InvalidModelStateResponseFactory,可以专门针对ApiController的模型验证错误生成自定义响应。
在Program.cs中添加配置:
builder.Services.Configure<ApiBehaviorOptions>(options => { options.InvalidModelStateResponseFactory = context => { // 收集并格式化错误信息 var validationErrors = context.ModelState .Where(entry => entry.Value.Errors.Any()) .ToDictionary( entry => entry.Key.Replace("$.", string.Empty), entry => entry.Value.Errors.Select(e => e.ErrorMessage).ToArray() ); // 构造自定义响应结构 var customErrorResponse = new { code = "40001", message = "请求数据验证失败", errors = validationErrors, timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ"), requestId = context.HttpContext.TraceIdentifier }; return new BadRequestObjectResult(customErrorResponse); }; });
效果说明
两种方法都能处理JSON反序列化错误(如Guid格式不匹配),最终返回的响应结构会完全按照你定义的字段输出,示例结构如下:
{ "code": "40001", "message": "请求数据验证失败", "errors": { "UserId": [ "The JSON value could not be converted to System.Guid. Path: $.UserId | LineNumber: 1 | BytePositionInLine: 16." ] }, "timestamp": "2024-05-20T12:30:00Z", "requestId": "00-6f50cde5f3c24d3f9ae15432b4878299-dff20b1783488d15-00" }
内容的提问来源于stack exchange,提问作者user246392
相关产品推荐
相关产品推荐

