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

ASP.NET Core中如何将特定异常映射为验证失败风格的ProblemDetails?

当然可以实现,而且有比CustomizeProblemDetails更优雅的方式——通过自定义ProblemDetailsFactory来直接覆盖异常对应的ProblemDetails创建逻辑,完全满足你提取异常中验证信息、返回400带错误数组的需求。

具体实现步骤

1. 定义承载验证错误的自定义异常(可选,也可复用现有异常)

如果你的业务场景需要传递自定义验证错误集合,可以先定义一个带错误信息的异常类:

public class ValidationFailureException : Exception
{
    public IDictionary<string, string[]> Errors { get; }

    public ValidationFailureException(IDictionary<string, string[]> errors)
        : base("存在验证失败项")
    {
        Errors = errors;
    }
}

2. 自定义ProblemDetailsFactory,覆盖异常处理逻辑

继承默认的DefaultProblemDetailsFactory,重写CreateExceptionProblemDetails方法,针对目标异常直接生成ValidationProblemDetails(带错误数组的验证失败格式):

public class CustomProblemDetailsFactory : DefaultProblemDetailsFactory
{
    public CustomProblemDetailsFactory(IOptions<ApiBehaviorOptions> options, IOptions<ProblemDetailsOptions> problemDetailsOptions)
        : base(options, problemDetailsOptions)
    {
    }

    public override ProblemDetails CreateExceptionProblemDetails(HttpContext httpContext, Exception exception, int? statusCode = null, string? title = null, string? type = null, string? detail = null, string? instance = null)
    {
        // 匹配自定义的验证失败异常
        if (exception is ValidationFailureException validationException)
        {
            var validationProblem = new ValidationProblemDetails(validationException.Errors)
            {
                Status = StatusCodes.Status400BadRequest,
                Title = "验证失败",
                Detail = "提交的内容存在验证错误,请检查后重试",
                Instance = httpContext.Request.Path
            };

            // 可添加额外扩展字段,比如请求追踪ID
            validationProblem.Extensions["traceId"] = httpContext.TraceIdentifier;

            return validationProblem;
        }

        // 其他异常沿用默认处理逻辑
        return base.CreateExceptionProblemDetails(httpContext, exception, statusCode, title, type, detail, instance);
    }
}

3. 注册自定义Factory到DI容器

在Program.cs中替换默认的ProblemDetailsFactory实现:

builder.Services.AddProblemDetails();

// 用自定义实现替换默认的ProblemDetailsFactory
builder.Services.AddSingleton<ProblemDetailsFactory, CustomProblemDetailsFactory>();

补充说明

  • 如果你的项目使用了FluentValidation等验证框架,抛出的是框架自带的ValidationException,可以直接将判断条件改为exception is ValidationException,然后从该异常的Errors属性中提取验证信息。
  • 这种方式直接从异常创建对应的ValidationProblemDetails,无需像CustomizeProblemDetails那样修改已生成的ProblemDetails的多个字段,逻辑更清晰,还能直接映射异常中的错误集合到响应的Errors数组。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 04:45:01