详解如何在ASP.NET Core Web API中以三种方式返回数据

 更新时间:2021年1月25日 10:00  点击:1247

在 ASP.NET Core 中有三种返回 数据 和 HTTP状态码 的方式,最简单的就是直接返回指定的类型实例,如下代码所示:

  [ApiController]
  [Route("[controller]")]
  public class WeatherForecastController : ControllerBase
  {
    [HttpGet]
    public IEnumerable<WeatherForecast> Get()
    {
      var rng = new Random();
      return Enumerable.Range(1, 5).Select(index => new WeatherForecast
      {
        Date = DateTime.Now.AddDays(index),
        TemperatureC = rng.Next(-20, 55),
        Summary = Summaries[rng.Next(Summaries.Length)]
      })
      .ToArray();
    }
  }

除了这种,也可以返回 IActionResult 实例 和 ActionResult <T> 实例。

虽然返回指定的类型 是最简单粗暴的,但它只能返回数据,附带不了http状态码,而 IActionResult 实例可以将 数据 + Http状态码 一同带给前端,最后就是 ActionResult<T> 它封装了前面两者,可以实现两种模式的自由切换,🐂吧。

接下来一起讨论下如何在 ASP.NET Core Web API 中使用这三种方式。

创建 Controller 和 Model 类

在项目的 Models 文件夹下新建一个 Author 类,代码如下:

  public class Author
  {
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
  }

有了这个 Author 类,接下来创建一个 DefaultController 类。

using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;

namespace IDGCoreWebAPI.Controllers
{
  [Route("api/[controller]")]
  [ApiController]
  public class DefaultController : ControllerBase
  {
    private readonly List<Author> authors = new List<Author>();
    public DefaultController()
    {
      authors.Add(new Author()
      {
        Id = 1,
        FirstName = "Joydip",
        LastName = "Kanjilal"
      });
      authors.Add(new Author()
      {
        Id = 2,
        FirstName = "Steve",
        LastName = "Smith"
      });
    }

    [HttpGet]
    public IEnumerable<Author> Get()
    {
      return authors;
    }

    [HttpGet("{id}", Name = "Get")]
    public Author Get(int id)
    {
      return authors.Find(x => x.Id == id);
    }
  }
}

在 Action 中返回 指定类型

最简单的方式就是在 Action 中直接返回一个 简单类型 或者 复杂类型,其实在上面的代码清单中,可以看到 Get 方法返回了一个 authors 集合,看清楚了,这个方法定义的是 IEnumerable<Author>。

[HttpGet]
public IEnumerable<Author> Get()
{
  return authors;
}

在 ASP.NET Core 3.0 开始,你不仅可以定义同步形式的 IEnumerable<Author>方法,也可以定义异步形式的 IAsyncEnumerable<T>方法,后者的不同点在于它是一个异步模式的集合,好处就是 不阻塞 当前的调用线程,关于 IAsyncEnumerable<T> 更多的知识,我会在后面的文章中和大家分享。

下面的代码展示了如何用 异步集合 来改造 Get 方法。

[HttpGet]
public async IAsyncEnumerable<Author> Get()
{
  var authors = await GetAuthors();
  await foreach (var author in authors)
  {
    yield return author;
  }
}

在 Action 中返回 IActionResult 实例

如果你要返回 data + httpcode 的双重需求,那么 IActionResult 就是你要找的东西,下面的代码片段展示了如何去实现。

[HttpGet]
public IActionResult Get()
{
 if (authors == null)
   return NotFound("No records");

 return Ok(authors);
}

上面的代码有 Ok,NotFound 两个方法,对应着 OKResult,NotFoundResult, Http Code 对应着 200,404。当然还有其他的如:CreatedResult, NoContentResult, BadRequestResult, UnauthorizedResult, 和 UnsupportedMediaTypeResult,都是 IActionResult 的子类。

在 Action 中返回 ActionResult<T> 实例

ActionResult<T> 是在 ASP.NET Core 2.1 中被引入的,它的作用就是包装了前面这种模式,怎么理解呢? 就是即可以返回 IActionResult ,也可以返回指定类型,从 ActionResult<TValue> 类下的两个构造函数中就可以看的出来。

public sealed class ActionResult<TValue> : IConvertToActionResult
{
  public ActionResult Result {get;}

  public TValue Value {get;}

  public ActionResult(TValue value)
  {
    if (typeof(IActionResult).IsAssignableFrom(typeof(TValue)))
    {
      throw new ArgumentException(Resources.FormatInvalidTypeTForActionResultOfT(typeof(TValue), "ActionResult<T>"));
    }
    Value = value;
  }

  public ActionResult(ActionResult result)
  {
    if (typeof(IActionResult).IsAssignableFrom(typeof(TValue)))
    {
      throw new ArgumentException(Resources.FormatInvalidTypeTForActionResultOfT(typeof(TValue), "ActionResult<T>"));
    }
    Result = (result ?? throw new ArgumentNullException("result"));
  }
}

有了这个基础,接下来看看如何在 Action 方法中去接这两种类型。

[HttpGet]
public ActionResult<IEnumerable<Author>> Get()
{
 if (authors == null)
    return NotFound("No records");
  return authors;
}

和文章之前的 Get 方法相比,这里直接返回 authors 而不需要再用 OK(authors) 包装,是不是一个非常好的简化呢? 接下来再把 Get 方法异步化,首先考虑下面返回 authors 集合的异步方法。

private async Task<List<Author>> GetAuthors()
{
  await Task.Delay(100).ConfigureAwait(false);
  return authors;
}

值得注意的是,异步方法必须要有至少一个 await 语句,如果不这样做的话,编译器会提示一个警告错误,告知你这个方法将会被 同步执行,为了避免出现这种尴尬,我在 Task.Delay 上做了一个 await。

下面就是更新后的 Get 方法,注意一下这里我用了 await 去调用刚才创建的异步方法,代码参考如下。

[HttpGet]
public async Task<ActionResult<IEnumerable<Author>>> Get()
{
  var data = await GetAuthors();
  if (data == null)
    return NotFound("No record");
  return data;
}

如果你有一些定制化需求,可以实现一个自定义的 ActionResult 类,做法就是实现 IActionResult 中的 ExecuteResultAsync 方法即可。

译文链接:https://www.infoworld.com/article/3520770/how-to-return-data-from-aspnet-core-web-api.html

到此这篇关于详解如何在ASP.NET Core Web API中以三种方式返回数据的文章就介绍到这了,更多相关ASP.NET Core Web API返回数据内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!

[!--infotagslink--]

相关文章

  • ASP.NET购物车实现过程详解

    这篇文章主要为大家详细介绍了ASP.NET购物车的实现过程,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-22
  • Springboot如何实现Web系统License授权认证

    这篇文章主要介绍了Springboot如何实现Web系统License授权认证,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-05-28
  • .NET Core下使用Kafka的方法步骤

    这篇文章主要介绍了.NET Core下使用Kafka的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22
  • 在ASP.NET 2.0中操作数据之七十二:调试存储过程

    在开发过程中,使用Visual Studio的断点调试功能可以很方便帮我们调试发现程序存在的错误,同样Visual Studio也支持对SQL Server里面的存储过程进行调试,下面就让我们看看具体的调试方法。...2021-09-22
  • C#使用Http Post方式传递Json数据字符串调用Web Service

    这篇文章主要为大家详细介绍了C#使用Http Post方式传递Json数据字符串调用Web Service,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
  • WebStorm无法正确识别Vue3组合式API的解决方案

    这篇文章主要介绍了WebStorm无法正确识别Vue3组合式API的解决方案,帮助大家更好的理解和学习使用vue框架,感兴趣的朋友可以了解下...2021-02-18
  • InterlliJ IDEA2020新建java web项目找不到Static Web的解决

    这篇文章主要介绍了InterlliJ IDEA2020新建java web项目找不到Static Web的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-09-02
  • 详解.NET Core 3.0 里新的JSON API

    这篇文章主要介绍了详解.NET Core 3.0 里新的JSON API,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22
  • 浅谈vue2的$refs在vue3组合式API中的替代方法

    这篇文章主要介绍了浅谈vue2的$refs在vue3组合式API中的替代方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-04-18
  • ASP.NET Core根据环境变量支持多个 appsettings.json配置文件

    这篇文章主要介绍了ASP.NET Core根据环境变量支持多个 appsettings.json配置文件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22
  • 记一次EFCore类型转换错误及解决方案

    这篇文章主要介绍了记一次EFCore类型转换错误及解决方案,帮助大家更好的理解和学习使用asp.net core,感兴趣的朋友可以了解下...2021-09-22
  • 详解在IDEA中将Echarts引入web两种方式(使用js文件和maven的依赖导入)

    这篇文章主要介绍了在IDEA中将Echarts引入web两种方式(使用js文件和maven的依赖导入),本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-07-11
  • jQuery mobile 移动web(6)

    这篇文章主要介绍了jQuery mobile 移动web(6)的相关资料,需要的朋友可以参考下...2015-12-21
  • 如何使用 JavaScript 操作浏览器历史记录 API

    这篇文章主要介绍了如何使用 JavaScript 操作浏览器历史记录 API,帮助大家更好的理解和使用JavaScript,感兴趣的朋友可以了解下...2020-11-24
  • 理解JavaScript中worker事件api

    这篇文章主要帮助大家理解JavaScript中worker事件api,对worker事件api有一个深刻了解,感兴趣的小伙伴们可以参考一下...2015-12-27
  • 如何设计一个安全的API接口详解

    在日常开发中,总会接触到各种接口,前后端数据传输接口,第三方业务平台接口,下面这篇文章主要给大家介绍了关于如何设计一个安全的API接口的相关资料,需要的朋友可以参考下...2021-08-12
  • C# Windows API应用之基于GetDesktopWindow获得桌面所有窗口句柄的方法

    这篇文章主要介绍了C# Windows API应用之基于GetDesktopWindow获得桌面所有窗口句柄的方法,结合实例形式分析了GetDesktopWindow函数用于获取窗口句柄的具体使用方法与相关注意事项,需要的朋友可以参考下...2020-06-25
  • 详解ASP.NET Core 中基于工厂的中间件激活的实现方法

    这篇文章主要介绍了ASP.NET Core 中基于工厂的中间件激活的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-22
  • vue设置全局访问接口API地址操作

    这篇文章主要介绍了vue设置全局访问接口API地址操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-14
  • asp.net通过消息队列处理高并发请求(以抢小米手机为例)

    这篇文章主要介绍了asp.net通过消息队列处理高并发请求(以抢小米手机为例),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22