【问题标题】:ASP.NET Web API 2 getting null on Request after sending a non-integer value for an integer parameter在为整数参数发送非整数值后,ASP.NET Web API 2 在请求上为空
【发布时间】:2021-03-27 22:19:37
【问题描述】:

我有一个关于 Asp.net Web Api 2 的项目。在测试其中一个端点时,我遇到了 .net 框架的一种有趣行为。

这是端点的简化版本:

    [Route("api/v1/bookings/documenttype/{clientId}/{companyCode}/{year}")]
    [HttpGet]
    [ResponseType(typeof(IEnumerable<UserVoucherType>))]
    public IHttpActionResult GetUserDocumentTypes(int clientId, string companyCode, 
                                                  int year, [FromUri] int? month = null)
    {
        //Do Some work
        return Ok();
    }

这里的问题是当我发送一个非整数值作为 'month' 参数的值而不是收到错误请求或类似的东西时,我在运行时得到 null,这会导致问题。例如,端点的一个消费者正在发送 '[1,2,3]' 并获取全年的所有数据,而不是收到错误消息。

例如,对于这个请求,我得到的值低于我在 ss 上指出的值: http://localhost:64652/api/v1/bookings/documenttype/1/0001/2019?month=[1,2,3]

现在我的问题是,我如何才能针对这样的案例返回错误的请求。

月份参数是可选的,我无法在端点上理解消费者是否故意发送此参数为空,或者他们发送的参数值无效。

有这个设置吗?我正在考虑编写一个自定义参数活页夹,但这不是过度工程吗?我认为框架的行为应该是默认返回错误请求还是我遗漏了什么?

【问题讨论】:

  • 你应该验证用户的输入,如果失败你可以返回 badrequest,阅读这里如何返回错误请求stackoverflow.com/a/10734690/1638261
  • @jomsk1e 我该如何验证参数,它正在变为空,这也可能是正常行为,因为它是可选参数,我在端点上无法理解的问题是有人真的发送月份参数null 或发送错误的值并变为 null。

标签: c# .net rest asp.net-web-api2


【解决方案1】:

您可以为可选参数创建一个模型并将 Range 属性应用于月份。

(这是.NET5,所以我使用[FromQuery],但这也适用于[FromUri]

public OkResult GetUserDocumentTypes(int clientId, string companyCode, 
                                            int year, [FromQuery] GetUserDocumentTypesOptionalInput optional)
{
//Do Some work
    return Ok();
}

public class GetUserDocumentTypesOptionalInput 
{
    [Range(1, 12, ErrorMessage = "Invalid month")]
    public int? Month {get; set; } // 1 or 0 based? 
}

如果您必须手动检查ModelState.IsValid 来捕获错误,这将取决于您的配置。


此外,&lt;TargetFramework&gt;net5.0&lt;/TargetFramework&gt;[FromQuery] int? month = null 将返回以下错误:

{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "One or more validation errors occurred.",
    "status": 400,
    "traceId": "00-65615fa2ff03a141b2cd80d7fc4f9dca-db45cf7466ae6f4f-00",
    "errors": {
        "month": [
            "The value '[1,2,3]' is not valid."
        ]
    }
}

【讨论】:

  • 感谢解答,我们使用的是4.6.1框架版本,有一段时间无法更新框架。但这看起来对我有帮助,是否有关于它的文档?
  • 我添加了一个适用于 .net 框架的选项。
  • 我猜你忘了添加助手类或?
【解决方案2】:

您可以更改 Route 属性以包含数据类型约束。

[Route("api/v1/bookings/documenttype/{clientId}/{companyCode}/{year:int{min:2000}/{month:int?}")]

我添加了 2 个约束 - 月份和年份的数据类型,以及年份的最小值。

更多详情请参考the official documentation from Microsoft.

【讨论】:

  • 不幸的是,更改路径不是我们的选择。所有可选参数必须是我们api中的查询参数。
  • 从用户的角度来看,这里的路径没有改变。用户仍将使用相同的路径,如 api/v1/bookings/documenttype/1/0001/2019?month=11 建议在服务器端,在 GetUserDocumentTypes() 顶部的 Route 属性中进行更改。让我们在那里为查询参数添加数据类型和值的约束。
猜你喜欢
  • 2023-03-25
  • 1970-01-01
  • 2016-11-08
  • 2016-06-23
  • 2013-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-28
相关资源
最近更新 更多