ASP.NET Core 中基于 Controller 的 Web API

基于 Controller 的 Web API

ASP.NET Wep API 的请求架构

客户端发送Http请求,Contoller响应请求,并从数据库读取数据,序列化数据,然后通过 Http Response返回序列化的数据。

ControllerBase 类

Web API 的所有controllers 一般继承于 ControllerBase 类,而不是Controller 类。

因为 Controller 类也继承自ControllerBase 类,但是支持views,而API一般不需要这个功能。

ControllerBase 提供了很多处理Http Request 和 Response方法,比如返回201结果的CreatedAtAction(表示成功创建资源):

csharp 复制代码
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<Pet> Create(Pet pet)
{
    pet.Id = _petsInMemoryStore.Any() ? 
             _petsInMemoryStore.Max(p => p.Id) + 1 : 1;
    _petsInMemoryStore.Add(pet);

    return CreatedAtAction(nameof(GetById), new { id = pet.Id }, pet);
}

其他一些主要方法:

  • Ok(),返回空的 http code 200
  • File(),返回文件和 http code 200,或者返回部分文件和 http code 206,或者不支持的Range和http code 416
  • PhysicalFile(),返回文件和 http code 200,或者返回部分文件和 http code 206,或者不支持的Range和http code 416
  • CreatedAtAction(),返回 http code 201
  • AcceptedAtAction(),返回 http code 202
  • NoContent(),返回 http code 204
  • Content(),返回具体结果,plain-text 格式
  • RedirectToActionPermanent(),返回 http code 301
  • RedirectToPagePermanent(),返回 http code 301
  • RedirectToPage(),返回 http code 302
  • RedirectToRoute(),返回 http code 302
  • RedirectToAction(),返回 http code 302
  • RedirectToActionPreserveMethod(),返回 http code 307
  • RedirectToPagePreserveMethod(),返回 http code 307
  • RedirectToActionPermanentPreserveMethod(),返回 http code 308
  • RedirectToPagePermanentPreserveMethod(),返回 http code 308
  • BadRequest(),返回 http code 400
  • Problem(),返回 http code 400
  • ValidationProblem(),返回 http code 400
  • Unauthorized(),返回 http code 401
  • Challenge(),返回 http code 401 或 403
  • Forbid() ,返回 http code 403
  • NotFound(),返回 http code 404
  • Conflict() ,返回 http code 409
  • UnprocessableEntity(),返回 http code 422
  • SignIn()
  • SignOut()
  • StatusCode(Int32)

重要的属性

  • ControllerContext
  • HttpContext,获取当前action的HttpContext
  • Url,IUrlHelper对象
  • Request,获取当前action的HttpRequest
  • Response,获取当前action的HttpResponse
  • RouteData,获取当前action的RouteData
  • User,获取当前action关联的User的ClaimsPrincipal

重要的Attributes

标识 Action的功能,包括:

  • ApiController\],表示这个Action为HTTP API responses服务。包括: * 必须要指定 \[Route("\[controller\]")

    • 自动验证model
    • 自动bind,包括[FromBody]等
    • 推断 multipart/form-data 的类型
  • Area\],指定Route

  • Route,指定Route
  • Consumes\],指定action 接收的数据类型,比如 \[Consumes("application/xml")\], \[Consumes("application/json")\],\[Consumes("application/x-www-form-urlencoded")

  • Produces\],指定action 返回的数据类型

  • HttpDelete\],

  • HttpPut\],

  • HttpOptions\],

  • NonAction\],表示不是Action方法

  • FromBody\],标识参数或属性可以绑定Body,比如: * public IActionResult Action3(\[FromBody\] Product product, \[FromBody\] Order order)

  • FromForm\],

Action 不一定要返回某个特定类型,ASP.NET Core 支持任何对象类型。

Actions 可以忽略 HttpRequest的Header的Accept,返回自己想要的类型。

如果返回结果类型不是IActionResult,那么会被序列化。

ControllerBase.Ok 默认返回Json类型。

Http Reponse 的 content-type: application/json; charset=utf-8.

csharp 复制代码
[HttpGet]
public IActionResult Get()
    => Ok(todoItemStore.GetList());

而下面这个,Content-Type是text/plain。

csharp 复制代码
[HttpGet("Version")]
public ContentResult GetVersion()
    => Content("v1.0.0");

协商结果类型

当HttpRequest 指定了Header的Accept,而 Action返回的类型是JSON时,会发生结果协商

ASP.NET Core 默认支持的结果类型:

  • application/json
  • text/json
  • text/plain
  1. 当Header的Accept中指定了一个类型是Action支持的类型时,则返回这个类型。
  2. 如果Action不支持指定的类型,且设置了MvcOptions.ReturnHttpNotAcceptable为true,则返回406。
  3. 用Action中第一个formatter 返回结果。
  4. 当Header的Accept中没有指定类型时,用Action中第一个formatter 返回结果。
  5. 当Header的Accept中包含"/"时,会被忽略,由Action决定。
  6. 当请求来自于浏览器时,Accept 会被忽略,由Action决定,默认返回JSON。
  7. 当请求来自于浏览器时,Accept 会被忽略,如果Host设置了RespectBrowserAcceptHeader为true,则使用浏览器的header。

如果 Action返回的结果是复杂类型时,.NET 会创建一个 ObjectResult,封装结果,然后序列化成协商的结果类型。比如:

csharp 复制代码
[HttpGet("{id:long}")]
public TodoItem? GetById(long id)
    => _todoItemStore.GetById(id);

设置成XML结果类型

csharp 复制代码
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers()
    .AddXmlSerializerFormatters();

设置成使用json.net的结果类型

默认的JSON格式是基于System.Text.Json的。

csharp 复制代码
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers()
    .AddNewtonsoftJson();
相关推荐
二闹3 分钟前
三个注解,到底该用哪一个?别再傻傻分不清了!
后端
用户490558160812515 分钟前
当控制面更新一条 ACL 规则时,如何更新给数据面
后端
林太白17 分钟前
Nuxt.js搭建一个官网如何简单
前端·javascript·后端
码事漫谈18 分钟前
VS Code 终端完全指南
后端
该用户已不存在43 分钟前
OpenJDK、Temurin、GraalVM...到底该装哪个?
java·后端
怀刃1 小时前
内存监控对应解决方案
后端
码事漫谈1 小时前
VS Code Copilot 内联聊天与提示词技巧指南
后端
Moonbit1 小时前
MoonBit Perals Vol.06: MoonBit 与 LLVM 共舞 (上):编译前端实现
后端·算法·编程语言
Moonbit1 小时前
MoonBit Perals Vol.06: MoonBit 与 LLVM 共舞(下):llvm IR 代码生成
后端·程序员·代码规范
Moonbit2 小时前
MoonBit Pearls Vol.05: 函数式里的依赖注入:Reader Monad
后端·rust·编程语言