【问题标题】:Restrict Asp.Net Web API numeric value bindings to base 10将 Asp.Net Web API 数值绑定限制为以 10 为底
【发布时间】:2018-06-18 05:17:33
【问题描述】:

在我拥有的 Asp.Net Web API 控制器中,有一个 PostAsync 方法将请求 JSON 主体绑定到模型类。

例如:

public class EmployeesController : ApiController
{
   ...
   public async Task<HttpResponseMessage> PostAsync([FromBody] Employee employee)
   {
      ...
   }
   ...
}

Employee 模型类包含一个数字属性 Height:

public class Employee
{
   ...
   public decimal Height { get; set; }
   ...
}

问题在于,当使用包含前导零的高度值的请求负载发布到上述控制器操作时,FromBodyAttribute 绑定器自动将该值转换为八进制,例如:010 被转换为十进制的值 8 .

示例请求正文:

{
   ...
   "Height": 010,
   ...
}

如何防止转换为八进制基数?

到目前为止我已经尝试过:

  1. this blog post 中描述的那样实现PropertyBindAttribute,但属性在转换为八进制基数后接收值,因此在绑定生命周期中使用此方法为时已晚
  2. 将属性转换为字符串类型,并使用自定义ValidationAttribute 来验证字符串的格式是否匹配数字十进制基值,然后将值转换为十进制并将其分配给另一个十进制属性/支持字段

【问题讨论】:

    标签: asp.net json asp.net-web-api deserialization octal


    【解决方案1】:

    为什么要发送带有前导零的值?这不是 JSON 中定义的数字。严格按照标准,它只是无效的 JSON,但一些解析器会很宽容,并将其解释为八进制,这似乎就是这里发生的事情。

    所以,.NET 认为您发送的不是标准十进制数,这就是它这样解释它的原因。作为一种解决方法,您可以通过字符串进行验证,但实际上调用者应该了解发送数据的正确格式。

    附:这个问题也与问题有关:Why is JSON invalid if an integer begins with 0

    【讨论】:

    • 感谢@ADyson 的回复和对相关问题的引用。为了提供一些上下文,我正在构建一个 ASP.Net Web-API,它为客户提供执行付款的选项。我希望将金额字段键入为十进制而不是字符串以公开更强类型的 API,但我无法预测客户发送包含前导零的金额,即使根据定义它是无效的 JSON。如果能够捕捉到此类情况并能够以错误消息进行响应,这对我来说很重要。问题是,当使用FromBody 属性时,这种情况会被忽视。
    • @LiroyAlima 我认为,如果您在规范中明确表示您接受 JSON 数据(包括小数),那么期望 Web 服务的调用者了解什么构成有效 JSON 并遵守那。即使原始输入来自用户,也由调用应用程序来验证数据是否采用适合传输的格式。如果他们选择忽略标准并向您发送模棱两可的数据,那是 他们的 问题,而不是您的问题,尽管如果 Web API 反序列化器不允许模棱两可可能会更好>
    • @LiroyAlima 我会在我们的文档中非常清楚地说明正确的格式是什么,并且可能会警告不正确的值可能会被错误解释,而对此的责任在于调用者。您可以在条款和条件中加入一些关于发送正确数据的责任是呼叫者的内容,这样您就可以将其作为法律问题,而不是软件问题!除了编写自己的反序列化器和/或模型绑定器或应用您已经描述的解决方法之外,您无法更改 ASP.NET 解释值的方式。
    • 感谢@ADyson 的回复。我了解应对挑战的一种方法是使用 EULA。我更感兴趣的是技术方面 - 如何实现一个模型绑定器,它将忽略前导“0”或前导“0x”以启用将值捕获为十进制(010 -> 转换为十进制 10) ,或拒绝请求(0x10 -> 被拒绝)。是否会提供适当的帮助来实施相同的操作。
    • ADyson,感谢反序列化和模型绑定之间的澄清。我们决定使用字符串输入,并编写自定义 ValidationAttribute。感谢您在此线程上的所有 cmets。
    猜你喜欢
    • 2022-12-07
    • 1970-01-01
    • 2013-06-06
    • 2015-10-17
    • 2012-03-14
    • 2020-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多