【问题标题】:ASP.NET Core customize the error when model binding failsASP.NET Core 自定义模型绑定失败时的错误
【发布时间】:2019-05-10 20:37:18
【问题描述】:

每当向 ASP.NET Core Web API 端点发送空值或无效值时,我都会尝试应用后端验证,但我不知道如何处理模型绑定失败错误。

在提交无效值时可能从ModelState 收到此错误:totalPrice: ["Could not convert string to decimal: . Path 'totalPrice', line 1, position 71."] 0: "Could not convert string to decimal: . Path 'totalPrice', line 1, position 71." 看起来模型绑定失败并且错误直接显示给客户端。

我有一个非常简单的控制器,上面装饰有ApiController 属性。

[ApiController]
public class ProductsController
{
    [HttpPost]
    public IActionResult Post([FromBody]CreateProductDto model)
    {    
        model.Id = await service.CreateProduct(model);

        return CreatedAtRoute(
            routeName: "GetProduct", 
            routeValues: new { id = model.Id }, 
            value: model
        );
    }
}

还有我的 DTO 模型

public class CreateProductDto
{
    [Required(ErrorMessage = "Invalid value")]
    public decimal totalPrice { get; set;}

    public int count { get; set; }
}

有没有办法从模型绑定错误中自定义文本?我想阻止发送敏感信息并向客户提供友好的反馈?

【问题讨论】:

  • 您收到模型绑定错误。您可以注册全局错误过滤器并根据其类型处理错误。
  • 我推荐一个自定义模型绑定器。这需要更多的工作,但可以为您提供更多的灵活性。

标签: asp.net asp.net-web-api


【解决方案1】:

您可以从 ConfigureServices 方法中的 Startup 类自定义错误消息。您可以查看详细信息Microsoft document。

这是一个例子 -

services.AddMvc(options =>
            {
                var iStrFactory = services.BuildServiceProvider().GetService<IStringLocalizerFactory>();
                var L = iStrFactory.Create("ModelBindingMessages", "WebUI"); // Resource file location 
                options.ModelBindingMessageProvider.SetValueIsInvalidAccessor((x) => L["The value '{0}' is invalid."]);

                options.ModelBindingMessageProvider.SetValueMustBeANumberAccessor((x) => L["The field {0} must be a number."]);
                options.ModelBindingMessageProvider.SetMissingBindRequiredValueAccessor((x) => L["A value for the '{0}' property was not provided.", x]);
                options.ModelBindingMessageProvider.SetAttemptedValueIsInvalidAccessor((x, y) => L["The value '{0}' is not valid for {1}.", x, y]);
                options.ModelBindingMessageProvider.SetMissingKeyOrValueAccessor(() => L["A value is required."]);
                options.ModelBindingMessageProvider.SetUnknownValueIsInvalidAccessor((x) => L["The supplied value is invalid for {0}.", x]);
                options.ModelBindingMessageProvider.SetValueMustBeANumberAccessor((x) => L["Null value is invalid.", x]);
            });

你可以阅读this的博客。

【讨论】:

  • 我真的希望这能解决问题,但它没有:/ 尝试了 ModelBindingMessageProviders 的所有可能属性。这是处理这些错误的非常优雅的方式。
  • 您可以使用 IValidatableObject 验证您的模型,也可以提供您的自定义错误消息。试试这个,docs.microsoft.com/en-us/aspnet/core/mvc/models/… 和 stackoverflow.com/questions/56588900/…
  • 你也可以看看这个stackoverflow.com/questions/3400542/…
  • 刚刚尝试过并对其进行了调试,但看起来错误是在 ValidationContext 之前引发的,并且在模型绑定时它来自 Newtonsoft.JSON 序列化程序。
  • 您可以在我的问题中看到代码。我只是想防止空格字符串被解析为十进制并且绑定因错误而爆炸。
猜你喜欢
  • 2019-12-07
  • 2018-12-11
  • 1970-01-01
  • 2023-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-09
  • 1970-01-01
相关资源
最近更新 更多