【问题标题】:How do I customize ASP.Net Core model binding errors?如何自定义 ASP.Net Core 模型绑定错误?
【发布时间】:2018-12-11 05:12:27
【问题描述】:

我只想从我的 Web API (Asp.net Core 2.1) 返回标准化的错误响应,但我似乎不知道如何处理模型绑定错误。

该项目刚刚从“ASP.NET Core Web 应用程序”>“API”模板创建。我有一个简单的动作定义为:

[Route("[controller]")]
[ApiController]
public class MyTestController : ControllerBase
{
    [HttpGet("{id}")]
    public ActionResult<TestModel> Get(Guid id)
    {
        return new TestModel() { Greeting = "Hello World!" };
    }
}

public class TestModel
{
    public string Greeting { get; set; }
}

如果我使用无效的 Guid(例如,https://localhost:44303/MyTest/asdf)向此操作发出请求,我会收到以下响应:

{
    "id": [
        "The value 'asdf' is not valid."
    ]
}

我在Startup.Configure 中有以下代码:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    JsonErrorMiddleware.CreateSingleton(env);

    if (!env.IsDevelopment())
    {
        app.UseHsts();
    }

    app
        .UseHttpsRedirection()
        .UseStatusCodePages(async ctx => { await JsonErrorMiddleware.Instance.Invoke(ctx.HttpContext); })
        .UseExceptionHandler(new ExceptionHandlerOptions() { ExceptionHandler = JsonErrorMiddleware.Instance.Invoke })
        .UseMvc()
}

JsonErrorMiddleware 只是一个将错误转换为我想要返回的正确形状并将它们放入响应的类。它根本不会因为模型绑定错误而被调用(不会抛出 Exception 并且不会调用 UseStatusCodePages)。

如何挂钩模型绑定,以便为项目中的所有操作提供标准化的错误响应?

我读过很多文章,但似乎都在讨论全局异常处理或验证错误。

【问题讨论】:

    标签: c# asp.net-core asp.net-core-webapi asp.net-core-middleware


    【解决方案1】:

    值得一提的是,ASP.NET Core 2.1 添加了[ApiController] 属性,其中包括通过返回BadRequestObjectResult 并传入ModelState 来自动处理模型验证错误。换句话说,如果你装饰你的具有该属性的控制器,您不再需要进行if (!ModelState.IsValid) 检查。

    此外,功能也是可扩展的。在Startup,可以添加:

    services.Configure<ApiBehaviorOptions>(o =>
    {
        o.InvalidModelStateResponseFactory = actionContext =>
            new BadRequestObjectResult(actionContext.ModelState);
    });
    

    以上只是默认情况下已经发生的事情,但您可以customize the lambda that InvalidModelStateResponseFactory is set to 以返回您喜欢的任何内容。

    【讨论】:

    • 为了完整性 - ApiBehaviorOptions 仅适用于装饰了 ApiController 属性的控制器!这也意味着还必须提供控制器本身的 Route 属性,并且完成绑定的方式也将发生变化。此处链接中提供的详细信息:stackoverflow.com/questions/45941246/…
    • ApiController 属性对我有帮助
    • 只有在你使用 PostConfigure 而不是 Configure 时才会生效(从 ASP.NET Core 3.1.8 开始)
    • @g.pickardou,谢谢,与我的情况相关。
    猜你喜欢
    • 2019-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-07
    • 2017-02-09
    • 1970-01-01
    • 2011-09-23
    • 2011-09-09
    相关资源
    最近更新 更多