如何在ActionResult ASP.NET Core 2.1中使用空合并运算符

时间:2019-02-04 12:03:14

标签: c# asp.net-core asp.net-core-2.1 null-coalescing

有人可以解释一下为什么我在以下方法的null合并中出错:

private readonly Product[] products = new Product[];

[HttpGet("{id}")]
public ActionResult<Product> GetById(int id)
{
    var product = products.FirstOrDefault(p => p.Id == id);
    if (product == null)
        return NotFound(); // No errors here
    return product; // No errors here

    //I want to replace the above code with this single line
    return products.FirstOrDefault(p => p.Id == id) ?? NotFound(); // Getting an error here: Operator '??' cannot be applied to operands of type 'Product' and 'NotFoundResult'
}  

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Category { get; set; }
    public decimal Price { get; set; }
}

我不明白的是为什么第一笔收益不需要任何强制转换而第二笔单行null合并无效!

我的目标是ASP.NET Core 2.1


编辑: 感谢@Hasan@dcastro的解释,但我不建议您在此处使用null换行,因为NotFound()在转换后将不会返回正确的错误代码!

return (ActionResult<Product>)products?.FirstOrDefault(p => p.Id == id) ?? NotFound();

2 个答案:

答案 0 :(得分:1)

发生错误,因为无法转换类型。

尝试一下:

[HttpGet("{id}")]
public ActionResult<Product> GetById(int id)
{
    var result = products?.FirstOrDefault(p => p.Id == id);
    return result != null ? new ActionResult<Product>(result) : NotFound();
}

答案 1 :(得分:1)

[HttpGet("{id}")]
[ProducesResponseType(200)]
[ProducesResponseType(404)]
public ActionResult<Product> GetById(int id)
{
    if (!_repository.TryGetProduct(id, out var product))
    {
        return NotFound();
    }

    return product;
}
  

在前面的代码中,当数据库中不存在该产品时,将返回404状态代码。如果产品确实存在,则   返回相应的Product对象。在ASP.NET Core 2.1之前,   退货;行本应返回Ok(product);。

从上面的代码和Microsoft相关page的解释中可以看出,在.NET Core 2.1之后,您无需像以前一样在控制器(ActionResult<T>)中返回确切的类型。要使用该功能,您需要添加属性以指示可能的响应类型,例如[ProducesResponseType(200)]等。

对于您而言,您需要做的基本上是向控制器方法中添加适当的响应类型属性,如下所示(因为您使用.NET Core 2.1进行开发)。

[HttpGet("{id}")]
[ProducesResponseType(200)]
[ProducesResponseType(404)]
public ActionResult<Product> GetById(int id)

编辑:

之所以不能编译程序(使用null-coalescing运算符),是因为返回类型不具有竞争力。在一种情况下,它返回产品类别,否则返回ActionResult<T>。按照我的建议更新代码后,我想您将可以使用null-coalescing运算符。

2。编辑 (在此处回答)

在深入研究问题之后,我发现当使用三元if语句或null合并运算符时,当可能返回多个类型时,我们需要明确指定期望从该语句生成的类型。如here之前的要求,编译器在不隐式转换的情况下不会决定返回哪种类型。因此,将返回类型强制转换为ActionResult即可解决问题。

return (ActionResult<Product>) products.FirstOrDefault(p=>p.id ==id) ?? NotFound();

但是最好如上所述添加响应类型属性。