在 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; }