在本教程中,将生成用于管理“待办事项”列表的 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 响应的对象。 此应用将有一个控制器。

  • 为了简化教程,应用不会使用永久数据库。 示例应用将待办事项存储在内存数据库中。

先决条件

安装以下组件:

请参阅此 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,然后选择“添加”。

将生成的代码替换为以下内容:

C#复制
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,然后选择“添加”。

将生成的代码替换为以下内容:

C#复制
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 文件的内容:

C#复制
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

将生成的代码替换为以下内容:

C#复制
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 类中。

C#复制
[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/todo
  • GET /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 路径构造如下所示:

  • 在控制器的路由特性中采用模板字符串:
C#复制
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 方法中:

C#复制
[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 操作

我们将向控制器添加 CreateUpdate 和 Delete 方法。 这些是主题的变体,因此在这里只提供代码并突出显示主要的差异。 添加或更改代码后生成项目。

创建

C#复制
[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
  • 在键值编辑器中,输入一个待办事项,例如
JSON复制
{
"name":"walk dog",
"isComplete":true
}
  • 选择“发送”

  • 选择下窗格中的“标头”选项卡,然后复制“位置”标头:

可以使用此位置标头 URI 访问刚刚创建的资源。 重新调用创建名为 "GetTodo" 路由时使用的 GetById 方法:

C#复制
[HttpGet("{id}", Name = "GetTodo")]
public IActionResult GetById(long id)

更新

C#复制
[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。

删除

C#复制
[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的更多相关文章

  1. 基于ASP.NET Core 创建 Web API

    使用 Visual Studio 创建项目. 文件->新建->项目,选择创建 ASP.NET Core Web 应用程序. 基于 ASP.NET Core 2.0 ,选择API,身份验证选 ...

  2. 使用 ASP.NET Core MVC 创建 Web API(二)

    使用 ASP.NET Core MVC 创建 Web API 使用 ASP.NET Core MVC 创建 Web API(一) 六.添加数据库上下文 数据库上下文是使用Entity Framewor ...

  3. 使用 ASP.NET Core MVC 创建 Web API(一)

    从今天开始来学习如何在 ASP.NET Core 中构建 Web API 以及每项功能的最佳适用场景.关于此次示例的数据库创建请参考<学习ASP.NET Core Razor 编程系列一> ...

  4. ASP.NET 5系列教程 (六): 在 MVC6 中创建 Web API

    ASP.NET 5.0 的主要目标之一是统一MVC 和 Web API 框架应用. 接下来几篇文章中您会了解以下内容: ASP.NET MVC 6 中创建简单的web API. 如何从空的项目模板中启 ...

  5. 使用 ASP.NET Core MVC 创建 Web API(五)

    使用 ASP.NET Core MVC 创建 Web API 使用 ASP.NET Core MVC 创建 Web API(一) 使用 ASP.NET Core MVC 创建 Web API(二) 使 ...

  6. 使用 ASP.NET Core MVC 创建 Web API(三)

    使用 ASP.NET Core MVC 创建 Web API 使用 ASP.NET Core MVC 创建 Web API(一) 使用 ASP.NET Core MVC 创建 Web API(二) 十 ...

  7. 使用 ASP.NET Core MVC 创建 Web API(四)

    使用 ASP.NET Core MVC 创建 Web API 使用 ASP.NET Core MVC 创建 Web API(一) 使用 ASP.NET Core MVC 创建 Web API(二) 使 ...

  8. 使用 ASP.NET Core MVC 创建 Web API——响应数据的内容协商(七)

    使用 ASP.NET Core MVC 创建 Web API 使用 ASP.NET Core MVC 创建 Web API(一) 使用 ASP.NET Core MVC 创建 Web API(二) 使 ...

  9. 使用 ASP.NET Core MVC 创建 Web API(六)

    使用 ASP.NET Core MVC 创建 Web API 使用 ASP.NET Core MVC 创建 Web API(一) 使用 ASP.NET Core MVC 创建 Web API(二) 使 ...

随机推荐

  1. Linux C++ UDP Socket通信实例

    环境:Linux 语言:C++ 通信方式:UDP 服务器端的步骤如下: 1. socket:      建立一个socket 2. bind:          将这个socket绑定在某个端口上(A ...

  2. 【转载】NeurIPS 2018 | 腾讯AI Lab详解3大热点:模型压缩、机器学习及最优化算法

    原文:NeurIPS 2018 | 腾讯AI Lab详解3大热点:模型压缩.机器学习及最优化算法 导读 AI领域顶会NeurIPS正在加拿大蒙特利尔举办.本文针对实验室关注的几个研究热点,模型压缩.自 ...

  3. Iterables vs. Iterators vs. Generators

    Reprinted from: Iterables vs. Iterators vs. Generators Occasionally I've run into situations of conf ...

  4. Python-eval()函数

    python eval() eval(expression, globals= None, locals= None) --官方文档中的解释: 将字符串str当成有效的表达式子来求值并返回计算结果. ...

  5. nginx反向代理解决跨域

    nginx作为反向代理服务器,就是把http请求转发到另一个或者一些服务器上.通过把本地一个url前缀映射到要跨域访问的web服务器上,就可以实现跨域访问.对于浏览器来说,访问的就是同源服务器上的一个 ...

  6. Git学习笔记07-删除文件

    在Git中,删除也是一种修改.先新建一个文件,添加并提交.然后删除下看看. 一般删除直接从工作区把文件删了,或者使用rm命令 ​ 这是使用git status查看状态,会告诉我们删了哪个文件 ​ 这个 ...

  7. mq for aix 清理步骤

    删除所有相关进程smit remove 删除mq删除mqm用户和用户组 如果unmount /cdrom 卸载不掉的话使用 fuser -xcu /cdrom rm /var/mqm

  8. <TCP/IP>ICMP报文的分类

    Internet控制报文协议,即为ICMP(Internet Control Message Protocal),用于主机,路由器之间传递信息,其目的是让我们能够检测网路的连线状况﹐也能确保连线的准确 ...

  9. MinGW GCC 7.2.0 2017年8月份出炉啦

    GCC720-for-MSYS2.7z for x86 x64 63.72 MB 发布日期: 2017-08-14 下载地址: https://forum.videohelp.com/attachme ...

  10. 毫秒倒计时小Demo

    Demo截图: Demo:Demo 上代码: <!DOCTYPE html> <html lang="en"> <head> <meta ...