是否有一种干净的方法将特定异常类型映射到验证失败样式 ProblemDetails?

问题描述 投票:0回答:2

在 ASP.NET Core 中启用

AddProblemDetails()
异常处理时,默认行为是在处理引发的异常时返回带有
ProblemDetails
的 HTTP 500。是否有任何规定指定某些异常返回验证失败样式问题详细信息,即带有一系列错误的 HTTP 400,而不是默认的服务器错误 500?

builder.Services.AddProblemDetails(opt => opt.CustomizeProblemDetails = ..);

但这允许我修改已经创建的

ProblemDetails
。我可以将这些值覆盖为验证失败的值(即将状态代码设置为 400),但这似乎有点笨拙,因为我需要更改一些字段,并且似乎无法将我的验证失败信息添加到错误集合中例外。

看来我可能缺少某个地方来挂钩并覆盖异常时

ProblemDetails
的实际创建。

谢谢

c# asp.net-core validation .net-core error-handling
2个回答
0
投票

我尝试了如下,是你想要的吗?

[HttpPost]
        public IActionResult Post(string Path)
        {
           
            throw new FileNotFoundException();
        }

在program.cs中:

builder.Services.AddProblemDetails(x =>
{
    x.CustomizeProblemDetails = ctx =>
    {
        var exception = ctx.HttpContext.Features.Get<IExceptionHandlerPathFeature>()?.Error;
        if(exception != null&&exception is FileNotFoundException)
        {
            ctx.ProblemDetails.Status = 400;
            ctx.ProblemDetails.Detail=exception.Message;
            ctx.HttpContext.Response.StatusCode = 400;
        }
        if(exception != null&& exception is ArgumentNullException)
        {
            ctx.ProblemDetails.Title = "Null exception";
            ctx.ProblemDetails.Detail = exception.Message;
            ctx.ProblemDetails.Status = 409;
          
        }
        ......
    };
});

var app = builder.Build();


app.UseExceptionHandler();

结果:

相关文档


0
投票

如果您使用的是 .net 6,那么据我所知,CustomizeProblemDetails 问题详细信息不是一个选项,但您可以在渲染之前编辑 ProblemDetails 对象,如下所示:

setup.IncludeExceptionDetails = (ctx, env) => true; // Always enable all details otherwise the details value is empty
setup.OnBeforeWriteDetails = (ctx, details) =>
{
    // In production get rid of the extended information such as exception details
    if (builder.Environment.IsProduction())
    {
        foreach (var key in details.Extensions.Keys)
        {
            if (key != "traceId")
            {
                details.Extensions.Remove(key);
            }
        };
    }
};

我这样做是为了让我仍然可以拥有人类可读的“详细信息”信息,但不是生产中的所有堆栈跟踪等

© www.soinside.com 2019 - 2024. All rights reserved.