不会生成 UI。
概述
以下是将创建的 API:
| API | 描述 | 请求正文 | 响应正文 |
|---|---|---|---|
| GET /api/todo | 获取所有待办事项 | 无 | 待办事项的数组 |
| GET /api/todo/{id} | 按 ID 获取项 | 无 | 待办事项 |
| POST /api/todo | 添加新项 | 待办事项 | 待办事项 |
| PUT /api/todo/{id} | 更新现有项 | 待办事项 | 无 |
| DELETE /api/todo/{id} | 删除项 | 无 | 无 |
下图显示了应用的基本设计。
-
curl 来测试应用。
-
模型表示为 C# 类,也称为 Plain Old C# Object (POCO)。
-
此应用将有一个控制器。
-
示例应用将待办事项存储在内存数据库中。
先决条件
安装以下组件:
- .NET Core 2.0.0 SDK 或更高版本。
- Visual Studio 2017 15.3 版或更高版本。
此 PDF 了解有关 ASP.NET Core 1.1 版本的信息。
创建项目
在 Visual Studio 中,选择“文件”菜单 >“新建” > “项目”。
将此项目命名为 TodoApi ,然后选择“确定”。
请不要选择“启用 Docker 支持”。
启动应用
Chrome、Edge 和 Firefox 将显示以下内容:
["value1","value2"]
添加模型类
在此示例中,唯一的一个模型是待办事项。
将文件夹命名为“Models”。
注意:模型类可位于项目的任意位置,但按照惯例会使用“Models”文件夹。
将此类命名为 TodoItem,然后选择“添加”。
将生成的代码替换为以下内容:
namespace TodoApi.Models
{
public class TodoItem
{
public long Id { get; set; }
public string Name { get; set; }
public bool IsComplete { get; set; }
}
}
创建 TodoItem 时,数据库将生成 Id。
创建数据库上下文
此类由 Microsoft.EntityFrameworkCore.DbContext 类派生而来。
将此类命名为 TodoContext,然后选择“添加”。
将生成的代码替换为以下内容:
using Microsoft.EntityFrameworkCore;
namespace TodoApi.Models
{
public class TodoContext : DbContext
{
public TodoContext(DbContextOptions<TodoContext> options)
: base(options)
{
}
public DbSet<TodoItem> TodoItems { get; set; }
}
}
注册数据库上下文
使用以下内容替换 Startup.cs 文件的内容:
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using TodoApi.Models;
namespace TodoApi
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<TodoContext>(opt => opt.UseInMemoryDatabase("TodoList"));
services.AddMvc();
}
public void Configure(IApplicationBuilder app)
{
app.UseMvc();
}
}
}
前面的代码:
- 删除未使用的代码。
- 指定将内存数据库注入到服务容器中。
添加控制器
将此类命名为 TodoController。
将生成的代码替换为以下内容:
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using TodoApi.Models;
using System.Linq;
namespace TodoApi.Controllers
{
[Route("api/[controller]")]
public class TodoController : Controller
{
private readonly TodoContext _context;
public TodoController(TodoContext context)
{
_context = context;
if (_context.TodoItems.Count() == 0)
{
_context.TodoItems.Add(new TodoItem { Name = "Item1" });
_context.SaveChanges();
}
}
}
}
前面的代码:
- 在接下来的部分中,我们将添加方法来实现 API。
- CRUD 方法中使用。
- 构造函数将一个项(如果不存在)添加到内存数据库。
获取待办事项
若要获取待办事项,请将下面的方法添加到 TodoController 类中。
[HttpGet]
public IEnumerable<TodoItem> GetAll()
{
return _context.TodoItems.ToList();
}
[HttpGet("{id}", Name = "GetTodo")]
public IActionResult GetById(long id)
{
var item = _context.TodoItems.FirstOrDefault(t => t.Id == id);
if (item == null)
{
return NotFound();
}
return new ObjectResult(item);
}
这些方法实现两种 GET 方法:
GET /api/todoGET /api/todo/{id}
以下是 GetAll 方法的 HTTP 响应示例:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/10.0
Date: Thu, 18 Jun 2015 20:51:10 GMT
Content-Length: 82
[{"Key":"1", "Name":"Item1","IsComplete":false}]
curl 查看 HTTP 响应。
路由和 URL 路径
每个方法的 URL 路径构造如下所示:
- 在控制器的路由特性中采用模板字符串:
namespace TodoApi.Controllers
{
[Route("api/[controller]")]
public class TodoController : Controller
{
private readonly TodoContext _context;
- 路由不区分大小写。
- 使用 Http [Verb] 特性的特性路由。
在 GetById 方法中:
[HttpGet("{id}", Name = "GetTodo")]
public IActionResult GetById(long id)
调用 GetById 时,它会将 URL 中“{id}”的值分配给方法的 id 参数。
路由到控制器操作。
返回值
(未经处理的异常将转换为 5xx 错误。)
GetById 具有两个不同的返回类型:
-
此通过返回
NotFound来实现。 -
此通过返回
ObjectResult来完成
启动应用
导航到刚刚创建的 Todo 控制器 http://localhost:port/api/todo。
实现其他的 CRUD 操作
添加或更改代码后生成项目。
创建
[HttpPost]
public IActionResult Create([FromBody] TodoItem item)
{
if (item == null)
{
return BadRequest();
}
_context.TodoItems.Add(item);
_context.SaveChanges();
return CreatedAtRoute("GetTodo", new { id = item.Id }, item);
}
[FromBody] 特性告诉 MVC 从 HTTP 请求正文获取待办事项的值。
10.2.2 201 已创建。
使用 Postman 发送创建请求
- 将 HTTP 方法设置为
POST - 选择“正文”单选按钮
- 选择“原始”单选按钮
- 将类型设置为 JSON
- 在键值编辑器中,输入一个待办事项,例如
{
"name":"walk dog",
"isComplete":true
}
-
选择“发送”
-
选择下窗格中的“标头”选项卡,然后复制“位置”标头:
路由时使用的 GetById 方法:
[HttpGet("{id}", Name = "GetTodo")]
public IActionResult GetById(long id)
更新
[HttpPut("{id}")]
public IActionResult Update(long id, [FromBody] TodoItem item)
{
if (item == null || item.Id != id)
{
return BadRequest();
}
var todo = _context.TodoItems.FirstOrDefault(t => t.Id == id);
if (todo == null)
{
return NotFound();
}
todo.IsComplete = item.IsComplete;
todo.Name = item.Name;
_context.TodoItems.Update(todo);
_context.SaveChanges();
return new NoContentResult();
}
若要支持部分更新,请使用 HTTP PATCH。
删除
[HttpDelete("{id}")]
public IActionResult Delete(long id)
{
var todo = _context.TodoItems.FirstOrDefault(t => t.Id == id);
if (todo == null)
{
return NotFound();
}
_context.TodoItems.Remove(todo);
_context.SaveChanges();
return new NoContentResult();
}
204(无内容)。