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

.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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 12:05:33