一. 概述
HTTP 不仅仅用于提供网页. HTTP 也是构建公开服务和数据的 API 强大平台. HTTP 简单灵活且无处不在. 几乎任何你能想到的平台都有一个 HTTP 库, 因此 HTTP 服务可以覆盖广泛的客户端, 包括浏览器, 移动设备和传统的桌面应用程序.
ASP.NET web API 是一个框架, 基于. NET Framework 或. NET Core 之上构建 Web API.
从本章开始学习 Web API 系列时, 先从一个示例开始, 下面使用 ASP.NET Core MVC 创建 Web API. 通过本次演示将了解到一个基础的 Web API 应用. 环境使用 vs 2017 +sql server 2012. 示例主要知识点包括:
(1)创建 Web API 项目.
(2)添加模型类.
(3)创建数据库上下文.
(4)注册数据库上下文.
(5)添加控制器.
(6)添加 CRUD 方法.
(7)配置路由和 URL 路径.
(8)指定返回值.
(9)使用 Fiddle 调用 Web API.
(10)使用 jQuery 调用 Web API.
在开发 Web API 之前, 先制定几个有针对性的 API 接口, 至于 API 接口业务很简单, 主要是演示如何应用 Web API.
API 接口 | 说明 | 请求报文 | 响应报文 |
GET /api/todo | 获取所有待办事项 | 无 | 待办事项的数据 |
GET /api/todo/{id} | 按 ID 获取项 | 无 | 待办事项 |
POST /api/todo | 添加新项 | 待办事项 | 待办事项 |
PUT /api/todo/{id} | 更新现有项 & nbsp; | 待办事项 | 无 |
DELETE /api/todo/{id} | 删除项 & nbsp; | 无 | 无 |
1.1 创建 Web 项目
(1)从 "文件" 菜单中选择 "新建"> "项目".
(2)选择 "ASP.NET Core Web 应用程序" 模板. 将项目命名为 TodoApi, 然后单击 "确定".
(3)在 "新建 ASP.NET Core Web 应用程序 - TodoApi" 对话框中, 选择 ASP.NET Core 版本. 选择 "API" 模板, 然后单击 "确定". 请不要选择 "启用 Docker 支持".
项目模板会创建 values API. 控制器方法中默认的 Http[Verb] 属性路由包括 GET,POST, PUT, DELETE 接口
1.2 添加模型类
在项目中, 添加 Models 文件夹, 新建一个 TodoItem 类, 如下所示:
- public class TodoItem
- {
- // 主键
- public long Id { get; set; }
- // 待办事项名称
- public string Name { get; set; }
- // 是否完成
- public bool IsComplete { get; set; }
- }
1.3 添加数据库上下文
在 "Models" 文件夹, 然后选择 "添加"> "类". 将类命名为 TodoContext, 如下所示:
- //using Microsoft.EntityFrameworkCore;
- public class TodoContext: DbContext
- {
- public TodoContext(DbContextOptions<TodoContext> options)
- : base(options)
- {
- }
- public DbSet<TodoItem> TodoItems { get; set; }
- }
1.4 注册上下文
在 ASP.NET Core 中, 服务 (如数据库上下文) 必须向依赖关系注入 (DI) 容器进行注册. 该容器向控制器提供服务. 这里使用 Microsoft.EntityFrameworkCore.SqlServer 数据提供程序. 再根据模型生成数据库表(库名 Todo, 有一个表 TodoItem). 关于如何安装数据提供程序, 以及如何用模型生成数据库表, 请参考 "asp.net core 系列第 20 篇" . 使用迁移生成数据库后, 如下所示:
1.5 添加控制器
在 Controllers 文件夹中, 选择 "API 控制器类" 模板. 将类命名为 TodoController.cs, 代码如下所示:
- [Route("api/[controller]")]
- [ApiController]// 添加特性, 代表是一个 Web API 控制器类
- public class TodoController : Controller
- {
- private readonly TodoContext _context;
- /// <summary>
- /// 实例化一个 EF 上下文, 进行数据库操作. 开始初始入库一条数据
- /// </summary>
- /// <param name="context"></param>
- public TodoController(TodoContext context)
- {
- _context = context;
- if (_context.TodoItems.Count() == 0)
- {
- // Create a new TodoItem if collection is empty,
- // which means you can't delete all TodoItems.
- _context.TodoItems.Add(new TodoItem { Name = "Item1" });
- _context.SaveChanges();
- }
- }
- }
1.6 添加 GET 方法
通过 GET 方法来查询待办事项的 API, 将以下方法添加到 TodoController 类中. 关于路由知识, 请参考 ASP.NET core 系列第 5 篇.
- /// <summary>
- /// 获取所有事项
- /// GET: API/Todo
- /// </summary>
- /// <returns></returns>
- [HttpGet]
- public async Task<ActionResult<IEnumerable<TodoItem>>> GetTodoItems()
- {
- //using Microsoft.EntityFrameworkCore;
- return await _context.TodoItems.ToListAsync();
- }
- /// <summary>
- /// 根据 id, 获取一条事项
- /// GET: API/Todo/5. id 是参数, 代表路由合并
- /// </summary>
- /// <param name="id"></param>
- /// <returns></returns>
- [HttpGet("{id}")]
- public async Task<ActionResult<TodoItem>> GetTodoItem(long id)
- {
- var todoItem = await _context.TodoItems.FindAsync(id);
- if (todoItem == null)
- {
- return NotFound();
- }
- return todoItem;
- }
启动 vs, 测试结果, 如下所示, 注意请求 wep API 地址与 action 的方法名没有关系, 是根据方法名之上的 Http[Verb]特性来确定 url 地址的:
1.7 路由和 URL 路径
(1) Route 特性
Route 是用来制定路由模板的, 在第 5 章中也讲到.[Route("api/[controller]")]中是以 API 开头, 替换[controller] 为控制器的名称, 按照惯例, 控制器类名称减去 "Controller" 后缀, 因此控制器名称为 "todo" , 路由不区分大小写.
(2) HttpGet
如果 [HttpGet] 属性具有路径模板, 例如:[HttpGet("{id}")], 则将其附加到路径(如: API/todo/1). 在这个示例中, "{id}" 是占位符变量, 用于待办事项的唯一标识符.
1.8 返回值
上面的 GetTodoItems 和 GetTodoItem 方法的返回类型是 ActionResult <T > 类型. ASP.NET Core 自动将对象序列化为 JSON, 并将 JSON 写入响应消息的正文中. 假设没有异常, 此返回类型的响应代码为 200. 未处理的异常被转换为 5xx 错误.
ActionResult 返回类型可以表示各种 HTTP 状态代码, 例如在上面的 GetTodoItem 方法中可以返回两个不同的状态值: 一个是成功的 200, 一个是 404 未到找. 所有的 HTTP 状态代码可以在 ControllerBase 中找到, 例如下图中的 Forbid() 是 Http 状态码 403,NoContent()是 Http 状态码 204 . 等等
二. 测试 Web API
下面简单使用 Fiddler 来测试一下增删改增. 先在本机 vs 2017 中启动该项目, 地址为 http://localhost:62271.
2.1 查询
在 Fiddler 工具中, 选择 GET, 输入查询的 http 地址, 右边是响应的 http 状态码 200, 以及查询的 JSON 结构对象.
2.2 新增
下面创建方法, 添加以下 PostTodoItem 方法, 在新增方法中调用了 CreatedAtAction 内置方法, 如果新增成功, 则返回 HTTP 201 状态代码. HTTP 201 是 HTTP POST 方法的标准响应, 该方法在服务器上创建新资源.
- //POST: API/Todo
- [HttpPost]
- public async Task<ActionResult<TodoItem>> PostTodoItem(TodoItem item)
- {
- _context.TodoItems.Add(item);
- await _context.SaveChangesAsync();
- return CreatedAtAction(nameof(GetTodoItem), new { id = item.Id }, item);
- }
2.3 修改
添加以下 PutTodoItem 方法, PutTodoItem 与 PostTodoItem 类似, 但是使用的是 HTTP PUT. 响应是 204(无内容). 根据 HTTP 规范, PUT 请求需要客户端发送整个更新的实体, 而不仅仅是更改. 若要支持部分更新, 请使用 HttpPatch 特性.
- // PUT: API/Todo/1
- [HttpPut("{id}")]
- public async Task<IActionResult> PutTodoItem(long id, TodoItem item)
- {
- if (id != item.Id)
- {
- //http 403
- return BadRequest();
- }
- // 当前传过来的实体添加到上下文, 并设置为修改
- _context.Entry(item).State = EntityState.Modified;
- await _context.SaveChangesAsync();
- return NoContent();
- }
2.4 删除
- // DELETE: API/Todo/2
- [HttpDelete("{id}")]
- public async Task<IActionResult> DeleteTodoItem(long id)
- {
- var todoitem = await _context.TodoItems.FindAsync(id);
- if (todoitem == null)
- {
- return NotFound();
- }
- _context.TodoItems.Remove(todoitem);
- await _context.SaveChangesAsync();
- return NoContent();
- }
最后: 关于 jQuery 调用 Web API, 不再演示, jQuery 调用的配置和注意事项, 请查看官网介绍.
参考文献:
ASP.NET Core 的 Web API
来源: https://www.cnblogs.com/MrHSR/p/10457763.html