【转】asp.net Core 系列【二】—— 使用 ASP.NET Core 和 VS2017 for Windows 创建 Web API
在本教程中,将生成用于管理“待办事项”列表的 Web API。 不会生成 UI。
概述
以下是将创建的 API:
| API | 描述 | 请求正文 | 响应正文 |
|---|---|---|---|
| GET /api/todo | 获取所有待办事项 | 无 | 待办事项的数组 |
| GET /api/todo/{id} | 按 ID 获取项 | 无 | 待办事项 |
| POST /api/todo | 添加新项 | 待办事项 | 待办事项 |
| PUT /api/todo/{id} | 更新现有项 | 待办事项 | 无 |
| DELETE /api/todo/{id} | 删除项 | 无 | 无 |
下图显示了应用的基本设计。

客户端使用的是 Web API(移动应用、浏览器等)。 在本教程中,我们不编写客户端, 而使用 Postman 或 curl 来测试应用。
模型是表示应用程序中的数据的对象。 在此示例中,唯一的模型是待办事项。 模型表示为 C# 类,也称为 Plain Old C# Object (POCO)。
控制器是处理 HTTP 请求并创建 HTTP 响应的对象。 此应用将有一个控制器。
为了简化教程,应用不会使用永久数据库。 示例应用将待办事项存储在内存数据库中。
先决条件
安装以下组件:
- .NET Core 2.0.0 SDK 或更高版本。
- 已安装 ASP.NET 和 Web 开发工作负载的 Visual Studio 2017 15.3 版或更高版本。
请参阅此 PDF 了解有关 ASP.NET Core 1.1 版本的信息。
创建项目
在 Visual Studio 中,选择“文件”菜单 >“新建” > “项目”。
选择“ASP.NET Core Web 应用程序(.NET Core)”项目模板。 将此项目命名为 TodoApi ,然后选择“确定”。

在“新建 ASP.NET Core Web 应用程序 - TodoApi”对话框中,选择“Web API”模板。 选择“确定”。 请不要选择“启用 Docker 支持”。

启动应用
在 Visual Studio 中,按 CTRL+F5 启动应用。 Visual Studio 启动浏览器并导航到 http://localhost:port/api/values,其中“端口”是随机选择的端口号。 Chrome、Edge 和 Firefox 将显示以下内容:
["value1","value2"]
添加模型类
模型是表示应用程序中的数据的对象。 在此示例中,唯一的一个模型是待办事项。
添加名为“Models”的文件夹。 在解决方案资源管理器中,右键单击项目。 选择“添加” > “新建文件夹”。 将文件夹命名为“Models”。
注意:模型类可位于项目的任意位置,但按照惯例会使用“Models”文件夹。
添加 TodoItem 类。 右键单击“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 类。 右键单击“Models”文件夹,然后选择“添加” > “类”。 将此类命名为 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();
}
}
}
前面的代码:
- 删除未使用的代码。
- 指定将内存数据库注入到服务容器中。
添加控制器
在解决方案资源管理器中,右键单击“控制器”文件夹。 选择“添加” > “新建项”。 在“添加新项”对话框中,选择“Web API 控制器类”模板。 将此类命名为 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。
- 构造函数使用依赖关系注入将数据库上下文 (
TodoContext) 注入到控制器中。 数据库上下文将在控制器中的每个 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}]
稍后在本教程中将演示如何使用 Postman 或 curl 查看 HTTP 响应。
路由和 URL 路径
[HttpGet] 特性指定 HTTP GET 方法。 每个方法的 URL 路径构造如下所示:
- 在控制器的路由特性中采用模板字符串:
namespace TodoApi.Controllers
{
[Route("api/[controller]")]
public class TodoController : Controller
{
private readonly TodoContext _context;
- 将“[Controller]”替换为控制器的名称,即在控制器类名称中去掉“Controller”后缀。 对于此示例,控制器类名称为“Todo”控制器,根名称为“todo”。 ASP.NET Core 路由不区分大小写。
- 如果
[HttpGet]特性具有路由模板(如[HttpGet("/products")]),则将它追加到路径。 此示例不使用模板。 有关详细信息,请参阅使用 Http [Verb] 特性的特性路由。
在 GetById 方法中:
[HttpGet("{id}", Name = "GetTodo")]
public IActionResult GetById(long id)
"{id}" 是 todo 项 的 ID 的占位符变量。 调用 GetById 时,它会将 URL 中“{id}”的值分配给方法的 id 参数。
Name = "GetTodo" 创建一个命名的路由,使你能够 HTTP 响应中链接到此路由。 稍后将使用示例进行解释。 有关详细信息,请参阅路由到控制器操作。
返回值
GetAll 方法返回 IEnumerable。 MVC 自动将对象序列化为 JSON,并将 JSON 写入响应消息的正文中。 在假设没有未经处理的异常的情况下,此方法的响应代码为 200。 (未经处理的异常将转换为 5xx 错误。)
相反,GetById 方法返回多个常规的 IActionResult 类型,它表示一系列返回类型。 GetById 具有两个不同的返回类型:
如果没有任何项与请求的 ID 匹配,此方法将返回 404 错误。 此通过返回
NotFound来实现。否则,此方法将返回具有 JSON 响应正文的 200。 此通过返回
ObjectResult来完成
启动应用
在 Visual Studio 中,按 CTRL+F5 启动应用。 Visual Studio 启动浏览器并导航到 http://localhost:port/api/values,其中“端口”是随机选择的端口号。 如果使用的是 Chrome、Edge 或 Firefox,则会显示数据。 如果使用的是 IE,IE 将提示你打开或保存 values.json 文件。 导航到刚刚创建的 Todo 控制器 http://localhost:port/api/todo。
实现其他的 CRUD 操作
我们将向控制器添加 Create、Update 和 Delete 方法。 这些是主题的变体,因此在这里只提供代码并突出显示主要的差异。 添加或更改代码后生成项目。
创建
[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);
}
这是 HTTP POST 方法,由 [HttpPost] 特性指示的。 [FromBody] 特性告诉 MVC 从 HTTP 请求正文获取待办事项的值。
CreatedAtRoute 方法返回 201 响应,这是在服务器上创建新资源的 HTTP POST 方法的标准响应。 CreatedAtRoute 还会向响应添加位置标头。 位置标头指定新建的待办事项的 URI。 请参阅 10.2.2 201 已创建。
使用 Postman 发送创建请求

- 将 HTTP 方法设置为
POST - 选择“正文”单选按钮
- 选择“原始”单选按钮
- 将类型设置为 JSON
- 在键值编辑器中,输入一个待办事项,例如
{
"name":"walk dog",
"isComplete":true
}
选择“发送”
选择下窗格中的“标头”选项卡,然后复制“位置”标头:

可以使用此位置标头 URI 访问刚刚创建的资源。 重新调用创建名为 "GetTodo" 路由时使用的 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();
}
Update 与 Create 类似,但是使用的是 HTTP PUT。 响应是 204(无内容)。 根据 HTTP 规范,PUT 请求需要客户端发送整个更新的实体,而不仅仅是增量。 若要支持部分更新,请使用 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(无内容)。

【转】asp.net Core 系列【二】—— 使用 ASP.NET Core 和 VS2017 for Windows 创建 Web API的更多相关文章
- 基于ASP.NET Core 创建 Web API
使用 Visual Studio 创建项目. 文件->新建->项目,选择创建 ASP.NET Core Web 应用程序. 基于 ASP.NET Core 2.0 ,选择API,身份验证选 ...
- 使用 ASP.NET Core MVC 创建 Web API(二)
使用 ASP.NET Core MVC 创建 Web API 使用 ASP.NET Core MVC 创建 Web API(一) 六.添加数据库上下文 数据库上下文是使用Entity Framewor ...
- 使用 ASP.NET Core MVC 创建 Web API(一)
从今天开始来学习如何在 ASP.NET Core 中构建 Web API 以及每项功能的最佳适用场景.关于此次示例的数据库创建请参考<学习ASP.NET Core Razor 编程系列一> ...
- ASP.NET 5系列教程 (六): 在 MVC6 中创建 Web API
ASP.NET 5.0 的主要目标之一是统一MVC 和 Web API 框架应用. 接下来几篇文章中您会了解以下内容: ASP.NET MVC 6 中创建简单的web API. 如何从空的项目模板中启 ...
- 使用 ASP.NET Core MVC 创建 Web API(五)
使用 ASP.NET Core MVC 创建 Web API 使用 ASP.NET Core MVC 创建 Web API(一) 使用 ASP.NET Core MVC 创建 Web API(二) 使 ...
- 使用 ASP.NET Core MVC 创建 Web API(三)
使用 ASP.NET Core MVC 创建 Web API 使用 ASP.NET Core MVC 创建 Web API(一) 使用 ASP.NET Core MVC 创建 Web API(二) 十 ...
- 使用 ASP.NET Core MVC 创建 Web API(四)
使用 ASP.NET Core MVC 创建 Web API 使用 ASP.NET Core MVC 创建 Web API(一) 使用 ASP.NET Core MVC 创建 Web API(二) 使 ...
- 使用 ASP.NET Core MVC 创建 Web API——响应数据的内容协商(七)
使用 ASP.NET Core MVC 创建 Web API 使用 ASP.NET Core MVC 创建 Web API(一) 使用 ASP.NET Core MVC 创建 Web API(二) 使 ...
- 使用 ASP.NET Core MVC 创建 Web API(六)
使用 ASP.NET Core MVC 创建 Web API 使用 ASP.NET Core MVC 创建 Web API(一) 使用 ASP.NET Core MVC 创建 Web API(二) 使 ...
随机推荐
- POJ 1458 Common Subsequence 最长公共子序列
题目大意:求两个字符串的最长公共子序列 题目思路:dp[i][j] 表示第一个字符串前i位 和 第二个字符串前j位的最长公共子序列 #include<stdio.h> #include&l ...
- Nginx系列1:ubuntu16.04编译出适合自己的nginx服务器
1.下载nginx nginx官网:nginx.org tar.gz文件 解压缩命令: wget https://nginx.org/download/nginx-1.14.2.tar.gz #下载n ...
- 2016521-Java-第八周学习总结
课本知识点 start() run()定义线程线程对象被调度之后所执行的操作 -sleep(int millsecond),必须在try-catch语句块中调用sleep方法 sAlive() 线程同 ...
- IntelliJ IDEA 配置
1.让IntelliJ IDEA 驼峰选择生效 驼峰选择,就是选择的时候按照驼峰规则选择单词,不是选择整个单词 让IntelliJ IDEA 驼峰选择生效 2.查看当前类中的所有方法 Alt+7 3. ...
- [转] pytorch指定GPU
查过好几次这个命令,总是忘,转一篇mark一下吧 转自:http://www.cnblogs.com/darkknightzh/p/6836568.html PyTorch默认使用从0开始的GPU,如 ...
- Pftriage:分析和追踪恶意文件,识别特征
项目地址 PFTriage:https://github.com/idiom/pftriage 参考 Pftriage:如何在恶意软件传播过程中对恶意文件进行分析 https://www.freebu ...
- Node.js的单元测试框架初体验
Mocha是一个功能丰富的JavaScript测试框架,运行在node.js平台和浏览器端,使异步测试变得简单和有趣.Mocha测试是串行的,允许灵活和准确的报告,同时将未捕获的异常映射到相应的测试用 ...
- mac使用技巧之截图
1.选定区域截图 command+shift+3 选定区域按住control,可以直接截图到剪切板, 按option可以进行比例缩放. 按住shift可以选定区域 按住空格键可以进入窗口截图模式. 2 ...
- Vue.js 子组件的异步加载及其生命周期控制
前端开发社区的繁荣,造就了很多优秀的基于 MVVM 设计模式的框架,而组件化开发思想也越来越深入人心.这其中不得不提到 Vue.js 这个专注于 VM 层的框架. 本文主要对 Vue.js 组件化开发 ...
- Git学习笔记03-工作区和暂存区
Git和其他版本控制工具不同的地方就是有暂存区的概念 工作区(Working Directory) 就是在电脑界面上能够看到的目录 版本库(Repository) 工作区下面有个一个.git文件夹,也 ...