在 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/art…
更多高质量干货:参见我的 GitHub: csharptranslate