• ASP.NET Core Web API 中控制器操作的返回类型


    ASP.NET Core Web API 中控制器操作的返回类型

    • 项目
    • 2022/04/18
    • 7 个参与者

    查看或下载示例代码如何下载

    ASP.NET Core 提供以下 Web API 控制器操作返回类型选项:

    本文档说明每种返回类型的最佳适用情况。

    特定类型

    最简单的操作返回基元或复杂数据类型(如 string 或自定义对象类型)。 请参考以下操作,该操作返回自定义 Product 对象的集合:

    [HttpGet]
    public List<Product> Get() =>
        _repository.GetProducts();
    

    在执行操作期间无需防范已知条件,返回特定类型即可满足要求。 上述操作不接受任何参数,因此不需要参数约束验证。

    如果存在多种返回类型,通常会将 ActionResult 返回类型与基元或复杂返回类型混合。 要支持此类操作,必须使用 IActionResultActionResult。 本文档中提供了多个返回类型的几个示例。

    返回 IEnumerable<T> 或 IAsyncEnumerable<T>

    ASP.NET Core 在将操作写入响应之前,对返回 IEnumerable 的结果进行缓冲。 考虑将操作签名的返回类型声明为 IAsyncEnumerable 以保证异步迭代。 最终,迭代模式基于要返回的基础具体类型。 MVC 自动对实现 IAsyncEnumerable<T> 的任何具体类型进行缓冲。

    请考虑以下操作,该操作将销售价格的产品记录返回为 IEnumerable<Product>

    [HttpGet("syncsale")]
    public IEnumerable<Product> GetOnSaleProducts()
    {
        var products = _repository.GetProducts();
    
        foreach (var product in products)
        {
            if (product.IsOnSale)
            {
                yield return product;
            }
        }
    }
    

    上述操作的 IAsyncEnumerable<Product> 等效项为:

    [HttpGet("asyncsale")]
    public async IAsyncEnumerable<Product> GetOnSaleProductsAsync()
    {
        var products = _repository.GetProductsAsync();
    
        await foreach (var product in products)
        {
            if (product.IsOnSale)
            {
                yield return product;
            }
        }
    }
    

    IActionResult 类型

    当操作中可能有多个 ActionResult 返回类型时,适合使用 IActionResult 返回类型。 ActionResult 类型表示多种 HTTP 状态代码。 派生自 ActionResult 的任何非抽象类都限定为有效的返回类型。 此类别中的某些常见返回类型为 BadRequestResult (400)、NotFoundResult (404) 和 OkObjectResult (200)。 或者,可以使用 ControllerBase 类中的便利方法从操作返回 ActionResult 类型。 例如,return BadRequest();return new BadRequestResult(); 的简写形式。

    由于此操作类型中有多个返回类型和路径,因此必须自由使用 [ProducesResponseType\] 特性。 此特性可针对 Swagger 等工具生成的 Web API 帮助页生成更多描述性响应详细信息。 [ProducesResponseType] 指示操作将返回的已知类型和 HTTP 状态代码。

    同步操作

    请参考以下同步操作,其中有两种可能的返回类型:

    [HttpGet("{id}")]
    [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(Product))]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public IActionResult GetById(int id)
    {
        if (!_repository.TryGetProduct(id, out var product))
        {
            return NotFound();
        }
    
        return Ok(product);
    }
    

    在上述操作中:

    • id 代表的产品不在基础数据存储中时,则返回 404 状态代码。 NotFound 便利方法作为 return new NotFoundResult(); 的简写调用。
    • 如果产品确实存在,则返回状态代码 200 及 Product 对象。 Ok 便利方法作为 return new OkObjectResult(product); 的简写调用。

    异步操作

    请参考以下异步操作,其中有两种可能的返回类型:

    [HttpPost]
    [Consumes(MediaTypeNames.Application.Json)]
    [ProducesResponseType(StatusCodes.Status201Created)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task<IActionResult> CreateAsync(Product product)
    {
        if (product.Description.Contains("XYZ Widget"))
        {
            return BadRequest();
        }
    
        await _repository.AddProductAsync(product);
    
        return CreatedAtAction(nameof(GetById), new { id = product.Id }, product);
    }
    

    在上述操作中:

    • 当产品说明包含“XYZ 小组件”时,返回 400 状态代码。 BadRequest 便利方法作为 return new BadRequestResult(); 的简写调用。
    • 在创建产品后,CreatedAtAction 便利方法生成 201 状态代码。 调用 CreatedAtAction 的替代方法是 return new CreatedAtActionResult(nameof(GetById), "Products", new { id = product.Id }, product);。 在此代码路径中,将在响应正文中提供 Product 对象。 提供了包含新建产品 URL 的 Location 响应标头。

    例如,以下模型指明请求必须包含 NameDescription 属性。 未在请求中提供 NameDescription 会导致模型验证失败。

    public class Product
    {
        public int Id { get; set; }
    
        [Required]
        public string Name { get; set; }
    
        [Required]
        public string Description { get; set; }
    
        public bool IsOnSale { get; set; }
    }
    

    如果应用了该 [ApiController\] 特性,则模型验证错误将导致400状态代码。 有关详细信息,请参阅自动 HTTP 400 响应

    ActionResult 与 IActionResult

    以下部分比较 ActionResultIActionResult

    ActionResult<T> 类型

    ASP.NET Core 包括 web API 控制器操作的ActionResult < T >返回类型。 它使您能够返回派生自 ActionResult 或返回 特定类型的类型。 ActionResult<T>IActionResult 类型相比,具有以下优势:

    • 可排除 [ProducesResponseType\] 特性的 Type 属性。 例如,[ProducesResponseType(200, Type = typeof(Product))] 简化为 [ProducesResponseType(200)]。 此操作的预期返回类型改为根据 ActionResult<T> 中的 T 进行推断。
    • 隐式强制转换运算符支持将 TActionResult 均转换为 ActionResult<T>。 将 T 转换为 ObjectResult,也就是将 return new ObjectResult(T); 简化为 return T;

    C# 不支持对接口使用隐式强制转换运算符。 因此,必须使用 ActionResult<T>,才能将接口转换为具体类型。 例如,在下面的示例中,使用 IEnumerable 不起作用:

    [HttpGet]
    public ActionResult<IEnumerable<Product>> Get() =>
        _repository.GetProducts();
    

    上面代码的一种修复方法是返回 _repository.GetProducts().ToList();

    大多数操作具有特定返回类型。 执行操作期间可能出现意外情况,不返回特定类型就是其中之一。 例如,操作的输入参数可能无法通过模型验证。 在此情况下,通常会返回相应的 ActionResult 类型,而不是特定类型。

    同步操作

    请参考以下同步操作,其中有两种可能的返回类型:

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

    在上述操作中:

    • 当产品不在数据库中时返回状态代码 404。
    • 如果产品确实存在,则返回状态代码 200 及相应的 Product 对象。

    异步操作

    请参考以下异步操作,其中有两种可能的返回类型:

    [HttpPost]
    [Consumes(MediaTypeNames.Application.Json)]
    [ProducesResponseType(StatusCodes.Status201Created)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task<ActionResult<Product>> CreateAsync(Product product)
    {
        if (product.Description.Contains("XYZ Widget"))
        {
            return BadRequest();
        }
    
        await _repository.AddProductAsync(product);
    
        return CreatedAtAction(nameof(GetById), new { id = product.Id }, product);
    }
    

    在上述操作中:

    • 在以下情况下,ASP.NET Core 运行时返回 400 状态代码 (BadRequest):
      • 已应用 [ApiController\] 属性,且模型验证失败。
      • 产品说明包含“XYZ 小组件”。
    • 在创建产品后,CreatedAtAction 方法生成 201 状态代码。 在此代码路径中,将在响应正文中提供 Product 对象。 提供了包含新建产品 URL 的 Location 响应标头。

    其他资源

  • 相关阅读:
    es6之class继承
    es6-class基本语法
    vue-cli3搭建pwa项目(一)
    vue 组件的通信方式
    react之组件&props
    React之元素渲染
    JSX
    JSX
    在项目中怎么使用react
    认识react
  • 原文地址:https://www.cnblogs.com/springsnow/p/16261869.html
Copyright © 2020-2023  润新知