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
  • Bind
  • Route,指定Route
  • Consumes\],指定action 接收的数据类型,比如 \[Consumes("application/xml")\], \[Consumes("application/json")\],\[Consumes("application/x-www-form-urlencoded")

  • Produces,指定action 返回的数据类型
  • HttpGet
  • HttpDelete
  • HttpPost
  • HttpPut
  • HttpPatch
  • HttpOptions
  • HttpHead
  • NonAction,表示不是Action方法
  • NonController,表示不是NonController方法
  • FromBody,标识参数或属性可以绑定Body,比如:
    • public IActionResult Action3(FromBody Product product, FromBody Order order)
  • FromHeader
  • FromForm

格式化Action 的返回结果

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();
相关推荐
葫芦和十三4 小时前
图解 MongoDB 05|文档模型设计:内嵌 vs 引用,反范式不是免费午餐
后端·mongodb·agent
不能放弃治疗8 小时前
单 Agent 实现模式
后端
IT_陈寒10 小时前
Redis内存爆了,原来我漏掉了这个致命配置
前端·人工智能·后端
fliter11 小时前
最后一块拼图:用 bitvec 构造 IPv4 包,真正做出自己的 Ping
后端
fliter12 小时前
用 Rust 解析并生成 ICMP 包:checksum、nom 与 cookie-factory
后端
蝎子莱莱爱打怪12 小时前
XZLL-IM干货系列 03|消息 ID 设计:一个 UUID 搞不定的事,我用两个 ID 解决了
后端·面试·开源
fliter12 小时前
从 panic 到 Result:用 Rust 重新整理一个 ping 项目的错误处理
后端
森蓝情丶12 小时前
我给 AI 搭了个法庭:一个前端仔的 LangGraph 实战全记录
前端·后端
JensCS猿12 小时前
从 Spring Boot 回看 SSM 框架:手动挡与自动挡的驾驶哲学
后端
爱勇宝12 小时前
干了近 8 年,一夜之间被裁:AI 时代,程序员最该害怕的不是 AI
前端·后端·程序员