【问题标题】:FromRoute does not set Url parameters in separate DTO classFromRoute 不在单独的 DTO 类中设置 Url 参数
【发布时间】:2020-09-28 19:19:14
【问题描述】:

在创建新的 Web API 项目时,您可能会想出需要 url 参数、正文值和查询的控制器端点,尤其是对于 PATCH 路由。

假设您想通过更改产品数量来更新购物篮。端点需要来自 url 的 order id 和 product id 以及来自 body 的金额。

[HttpPatch("{orderId}/products/{productId}")]
public async Task<IActionResult> Update(Dto dto)
{
    return Ok(dto);
}

匹配的Dto 应该包含整个请求中的值

public class Dto
{
    [FromRoute]
    public int OrderId { get; set; }

    [FromRoute]
    public int ProductId { get; set; }

    [FromBody]
    public int Amount { get; set; }
}

当通过PATCH调用API时https://localhost:5001/orders/123/products/456Amount是正确的,但两个ID参数都是0。我认为它们不会被设置,将有它们的默认值。

我错过了什么吗?

【问题讨论】:

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


    【解决方案1】:

    我遇到了同样的问题。这对我有帮助。

    在控制器中,需要指定[FromRoute]:

    [HttpPatch("{orderId}/products/{productId}")]
    public async Task<IActionResult> Update([FromRoute] Dto dto)
    {
        return Ok(dto);
    }
    

    在DTO中,在应该从body中获取的字段上,需要指定[FromBody]:

    public class Dto
    {
        public int OrderId { get; set; }
    
        public int ProductId { get; set; }
    
        [FromBody]
        public int Amount { get; set; }
    }
    

    【讨论】:

      【解决方案2】:

      由于这是一个 web api 项目,[ApiController] 属性将推理规则应用于动作参数的默认数据源。 Dto 是一个复杂类型,所以默认使用 [FromBody]。

      当 [FromBody] 应用于复杂类型参数时,任何应用于其属性的绑定源属性都将被忽略。这就是您无法获取 OrderId 和 ProductId 的原因,它们的 [FromRoute] 属性将被忽略。

      可以从官方文档中找到:

      https://docs.microsoft.com/en-us/aspnet/core/web-api/?view=aspnetcore-3.1#binding-source-parameter-inference

      https://docs.microsoft.com/en-us/aspnet/core/mvc/models/model-binding?view=aspnetcore-3.1#frombody-attribute

      一种解决方案是您可以单独接收它们:

      [HttpPatch("{orderId}/products/{productId}")]
      public async Task<IActionResult> Update(Dto dto, int orderid, int productId)
      {
          return Ok(dto);
      }
      

      【讨论】:

      • 所以没有办法将它们合并在一起?因为我可以使用 AutoMapper 直接将整个 DTO 映射到另一个对象,而您上面提供的解决方案会破坏这个:/
      • 好像不行,但是可以在action中将id填到dto中。
      • hm 问题是[FromQuery] 提出了更多问题。所以 DTO 只对身体有效?是否有任何解决方案,例如3 个 DTO(ID、正文、查询)并稍后将它们合并在一起?这看起来有点乱
      • 是的,如果在参数前注明出处,他会从对应的出处查找数据。
      猜你喜欢
      • 2018-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多