ASP.NET Core 中文文档 第二章 指南(2)用 Visual Studio 和 ASP.NET Core MVC 创建首个 Web API

时间:2022-09-07 10:54:59

原文:Building Your First Web API with ASP.NET Core MVC and Visual Studio

作者:Mike WassonRick Anderson

翻译:谢炀(kiler)

校对:何镇汐刘怡(AlexLEWIS)后知后觉

HTTP 协议不仅仅提供网页服务。它也是一个构建公开服务和数据 API 的强大平台。HTTP 协议是简单、灵活、无处不在的。几乎你能想到的任何平台上都有 HTTP 支持,所以 HTTP 服务能够发送到多种客户端, 包括浏览器,移动设备和传统的桌面应用程序。

在本教程中,你将创建一个简单的 Web API 来管理一个 "to-do" 列表。在本教程中你无需编写任何 UI 代码。

ASP.NET Core 已经内置了用 MVC 架构 构建 Web API 的支持。统一了两个框架使得它易于构建应用程序,包括用户界面(HTML)和 API,因为现在它们共享相同的代码库和管道。

注意

如果你想把一个老的 Web API 应用程序迁移到 ASP.NET Core, 参考从 ASP.NET Web API 迁移


总览

这是你需要创建的 API :

API 描述 请求正文 响应正文
GET /api/todo 获取所有的to-do items Array of to-do items
GET /api/todo/{id} 通过ID获取item To-do item
POST /api/todo 添加一个新的item To-do item To-do item
PUT /api/todo/{id} 更新已经存在的item To-do item
DELETE /api/todo/{id} 删除指定的item

下面的图表展示了应用程序的基本设计:

ASP.NET Core 中文文档 第二章 指南(2)用 Visual Studio 和 ASP.NET Core MVC 创建首个 Web API

  • 不管是哪个调用 API 的客户端(浏览器、移动应用等)。我们不会在本教程编写客户端。
  • model 是一个代表你应用程序数据的类。在本案例中,只有一个模型 to-do 项。模型表现为简单 C# 类型 (POCOs),
  • controller 是一个处理 HTTP 请求并返回 HTTP 响应的对象。这个示例程序将只会有一个 controller。
  • 为了保证教程简单我们不使用数据库。作为替代,我们会把 to-do 项存入内存。但是我们依然包含了一个数据访问层(不重要的),用来隔离 Web API和数据层。如果想使用数据库,参考用 Visual Studio 创建 ASP.NET Core MVC 应用程序

安装 Fiddler

我们不创建客户端,我们使用 Fiddler 来测试 API。Fiddler 是一个 Web 调试工具可以让您撰写的 HTTP 请求进行发送并查看原始的 HTTP 响应。


创建项目

启动 Visual Studio。从 File 菜单, 选择 New > Project

选择 ASP.NET Core Web Application 项目模版。项目命名为 TodoApi 并且点击 OK

ASP.NET Core 中文文档 第二章 指南(2)用 Visual Studio 和 ASP.NET Core MVC 创建首个 Web API

New ASP.NET Core Web Application (.NET Core) - TodoApi 对话框中,选择 Web API 模版。点击 OK

ASP.NET Core 中文文档 第二章 指南(2)用 Visual Studio 和 ASP.NET Core MVC 创建首个 Web API


添加模型类

模型表示应用程序中的数据对象。在本示例中,唯一使用到的模型是一个 to-do 项。

添加一个名为 "Models" 的目录。在解决方案浏览器中, 右击项目。选择 Add > New Folder。把目录名命名为 Models

ASP.NET Core 中文文档 第二章 指南(2)用 Visual Studio 和 ASP.NET Core MVC 创建首个 Web API

注意

你可以把模型类放到项目的任何地方,但是 Models 是约定的默认目录。

下一步,添加一个 TodoItem 类。右击 Models 目录并选择 Add > New Item

Add New Item 对话框中,选择 Class 模版。命名类为 TodoItem 并点击 OK

ASP.NET Core 中文文档 第二章 指南(2)用 Visual Studio 和 ASP.NET Core MVC 创建首个 Web API

将生成代码替换为:

namespace TodoApi.Models
{
public class TodoItem
{
public string Key { get; set; }
public string Name { get; set; }
public bool IsComplete { get; set; }
}
}

添加仓储类

repository 类是一个封装了数据层的类,包含了获取数据并映射到实体模型类的业务逻辑。 尽管本例中不使用数据库,但依旧值得去思考 Repository 是如何注入到我们的 Controller 的。在 Models 目录下创建 repository 代码。

定义一个名为 ITodoRepository 的 repository 接口. 通过类模版 (Add New Item > Class)。

using System.Collections.Generic;

namespace TodoApi.Models
{
public interface ITodoRepository
{
void Add(TodoItem item);
IEnumerable<TodoItem> GetAll();
TodoItem Find(string key);
TodoItem Remove(string key);
void Update(TodoItem item);
}
}

接口定义了基本的 CRUD 操作。

下一步,添加一个实现 ITodoRepository 接口的 TodoRepository 类:

using System;
using System.Collections.Generic;
using System.Collections.Concurrent; namespace TodoApi.Models
{
public class TodoRepository : ITodoRepository
{
static ConcurrentDictionary<string, TodoItem> _todos =
new ConcurrentDictionary<string, TodoItem>(); public TodoRepository()
{
Add(new TodoItem { Name = "Item1" });
} public IEnumerable<TodoItem> GetAll()
{
return _todos.Values;
} public void Add(TodoItem item)
{
item.Key = Guid.NewGuid().ToString();
_todos[item.Key] = item;
} public TodoItem Find(string key)
{
TodoItem item;
_todos.TryGetValue(key, out item);
return item;
} public TodoItem Remove(string key)
{
TodoItem item;
_todos.TryGetValue(key, out item);
_todos.TryRemove(key, out item);
return item;
} public void Update(TodoItem item)
{
_todos[item.Key] = item;
}
}
}

生成应用程序确保没有任何编译错误。


注册仓储

定义 repository 接口, 我们可以从使用它的 MVC Controller 解耦仓储类,而不是直接在 Controller 里面实例化 TodoRepository ,我们将会用 ASP.NET Core 内置功能注入 ITodoRepository ,更多请参考依赖注入

这种方式可以更容易地对你的 Controller 进行单元测试。单元测试应该注入一个 Mock 或 stub 的 ITodoRepository。通过这样的方式测试范围可以限制在业务逻辑层而非数据访问层。

为了注入 repository 到 controller,我们必须注册DI容器。打开 Startup.cs 文件。添加以下指令:

using TodoApi.Models;

ConfigureServices 方法中,添加高亮方法:

public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
// Add our repository type,下行高亮
services.AddSingleton<ITodoRepository, TodoRepository>();
}

添加控制器

在解决方案浏览器中,右击 Controllers 目录。选择 Add > New Item。在 Add New Item 对话框中,选择 Web API Controller Class 模版。命名为 TodoController

将生成的代码替换为如下代码:

using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using TodoApi.Models; namespace TodoApi.Controllers
{
[Route("api/[controller]")]
public class TodoController : Controller
{
public TodoController(ITodoRepository todoItems)
{
TodoItems = todoItems;
}
public ITodoRepository TodoItems { get; set; }
}
}

这里定义了一个空的 controller 类。下一个章节,我们将添加代码来实现 API。


获取 to-do 列表

为了获取 to-do 项,添加下列方法到 TodoController 类。

public IEnumerable<TodoItem> GetAll()
{
return TodoItems.GetAll();
} [HttpGet("{id}", Name = "GetTodo")]
public IActionResult GetById(string id)
{
var item = TodoItems.Find(id);
if (item == null)
{
return NotFound();
}
return new ObjectResult(item);
}

以下是 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":"4f67d7c5-a2a9-4aae-b030-16003dd829ae","Name":"Item1","IsComplete":false}]

在后面的教程中,我将会告诉你如何使用 Fiddler 工具查看 HTTP 响应。

路由和 URL 路径

[HttpGet] 特性标明这些方法支持 HTTP GET,对 controller 中的方法标注 url 路径,有以下步骤:

  • 在 controller 特性中标注模板:[Route("api/[controller]")]
  • 替换模板中的 [Controller] 为实际 controller 名称(在这里和以前一样,约定优于配置,所有 controller 都必须以 Controller 结尾,模板中则可以省略 Controller 后缀,译者注)。比如本例中的 TodoController,把 {controller} 换成 todo 即可。在 ASP.NET MVC Core 是大小写不敏感的。
  • 如果 [HttpGet] 也有一个模板,可以把它附加到路径后面,本例中不使用模板字符串。

对于 GetById 方法,在实际 HTTP 请求中 {id} 是一个占位符,客户端运行时使用 todo 的 ID 属性;当 MVC 调用 GetById 时,会把 {id} 占位符分配到 Url 方法的 id 参数中。

更换 "api/todo" 的启动 Url

  • 右击项目 > Properties
  • 选择 Debug 选项卡,将 Launch URL 的值设置为 api/todo

ASP.NET Core 中文文档 第二章 指南(2)用 Visual Studio 和 ASP.NET Core MVC 创建首个 Web API

了解更多有关请求路由的信息请参考路由到控制器 Action

返回值

GetAll 方法返回 CLR 对象。MVC 自动把对象序列化为 JSON 并把 JSON 对象写入响应消息正文。响应状态码为 200,假设没有未处理异常的情况下。(未处理异常一般会被转化为 5xx 错误。)

相反,GetById 将会返回 IActionResult 类型,它代表了更加通用的结果对象。因为 GetById 有两个不同的返回值:

  • 如果没有数据项可以匹配 ID,方法会返回 404 错误,并最终以返回 NotFound 告终。
  • 否则方法会返回 200 以及 JSON 响应正文。并最终以返回 ObjectResult 告终。

使用 Fiddler 调用 API

这一步是可选的,但是有助于我们查看 Web API 返回的原始 HTTP 响应。

在 Visual Studio 中,点击 ^F5 启动项目。Visual Studio 启动浏览器并导航到 http://localhost:port/api/todoport 是一个随机数。如果你使用 Chrome、Edge 或者 Firefox 浏览器,todo 数据将会被显示。如果你使用 IE,IE 将会弹出窗口提示要求打开或者保存 todo.json 文件。

启动 Fiddler,从 File 菜单,取消选择 Capture Traffic 选项。这个会关闭捕获 HTTP traffic。

ASP.NET Core 中文文档 第二章 指南(2)用 Visual Studio 和 ASP.NET Core MVC 创建首个 Web API

选择 Composer 页面。在 Parsed 选项卡中,输入 http://localhost:port/api/todoport 是实际的端口号。点击 Execute 发送请求。

ASP.NET Core 中文文档 第二章 指南(2)用 Visual Studio 和 ASP.NET Core MVC 创建首个 Web API

结果会显示在 sessions 列表中,响应码是200。使用 Inspectors 选项卡来查看响应内容,包括请求正文。

ASP.NET Core 中文文档 第二章 指南(2)用 Visual Studio 和 ASP.NET Core MVC 创建首个 Web API


实现其他的 CRUD 操作

最后一步是为 Controller 增加 CreateUpdate 以及 Delete 这三个方法。这些方法都是围绕着一个主题,所以我将只列出代码以及标注出主要的区别。

Create

[HttpPost]
public IActionResult Create([FromBody] TodoItem item)
{
if (item == null)
{
return BadRequest();
}
TodoItems.Add(item);
return CreatedAtRoute("GetTodo", new { controller = "Todo", id = item.Key }, item);
}

这是一个 HTTP POST 方法,用 [HttpPost] 特性声明。[FromBody] 特性告诉 MVC 从 HTTP 请求的正文中获取 to-do 项的值。

当通过客户端向服务器发出 POST 请求来创建新资源时,CreatedAtRoute 方法将返回标准的 201 响应。CreateAtRoute 还把 Location 头信息加入到了响应。Location 头信息指定新创建的 todo 项的 URI。查看 10.2.2 201 Created

我们使用 Fiddler 来创建和发送一个请求:

  1. Composer 页面,从下拉框选择 POST。
  2. 在请求头的文本框中, 添加 Content-Type: application/json,意思是 Content-Type 类型的头信息值为 application/json。Fiddler 会自动添加 Content-Length 头信息。
  3. 在请求正文的文本框,输入以下内容:{"Name":"<你的 to-do 项目>"}
  4. 点击 Execute

ASP.NET Core 中文文档 第二章 指南(2)用 Visual Studio 和 ASP.NET Core MVC 创建首个 Web API

这是一个简单的 HTTP 会话. 使用 Raw 选项卡查看会话数据.

Request:

POST http://localhost:29359/api/todo HTTP/1.1
User-Agent: Fiddler
Host: localhost:29359
Content-Type: application/json
Content-Length: 33 {"Name":"Alphabetize paperclips"}

Response:

HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8
Location: http://localhost:29359/api/Todo/8fa2154d-f862-41f8-a5e5-a9a3faba0233
Server: Microsoft-IIS/10.0
Date: Thu, 18 Jun 2015 20:51:55 GMT
Content-Length: 97 {"Key":"8fa2154d-f862-41f8-a5e5-a9a3faba0233","Name":"Alphabetize paperclips","IsComplete":false}

Update

[HttpPut("{id}")]
public IActionResult Update(string id, [FromBody] TodoItem item)
{
if (item == null || item.Key != id)
{
return BadRequest();
} var todo = TodoItems.Find(id);
if (todo == null)
{
return NotFound();
} TodoItems.Update(item);
return new NoContentResult();
}

Update 类似于 Create,但是使用 HTTP PUT。响应是 204 (No Content)。根据 HTTP 规范,PUT 请求要求客户端发送整个实体更新,而不仅仅是增量。为了支持局部更新,请使用 HTTP PATCH。

ASP.NET Core 中文文档 第二章 指南(2)用 Visual Studio 和 ASP.NET Core MVC 创建首个 Web API

Delete

[HttpDelete("{id}")]
public void Delete(string id)
{
TodoItems.Remove(id);
}

方法返回 204 (无内容) 响应。这意味着客户端会收到 204 响应即使该项目已被删除,或者根本不存在。有两种方法来处理请求删除不存在资源的问题:

  • "Delete" 代表「删除一个已存在的项」,如果不存在返回 404。
  • "Delete" 代表「确保该项不在集合中」,如果项目不在集合中返回 204。

无论哪种方法是合理的。如果收到 404 错误,客户端将需要处理这种情况。

ASP.NET Core 中文文档 第二章 指南(2)用 Visual Studio 和 ASP.NET Core MVC 创建首个 Web API


下一步

返回目录

ASP.NET Core 中文文档 第二章 指南(2)用 Visual Studio 和 ASP.NET Core MVC 创建首个 Web API的更多相关文章

  1. ASP&period;NET Core 中文文档 第二章 指南(3)用 Visual Studio 发布一个 Azure 云 Web 应用程序

    原文:Getting Started 作者:Rick Anderson 翻译:谢炀(Kiler) 校对:孟帅洋(书缘).刘怡(AlexLEWIS).何镇汐 设置开发环境 安装最新版本的 Azure S ...

  2. ASP&period;NET Core 中文文档 第二章 指南(4&period;6)Controller 方法与视图

    原文:Controller methods and views 作者:Rick Anderson 翻译:谢炀(Kiler) 校对:孟帅洋(书缘) .张仁建(第二年.夏) .许登洋(Seay) .姚阿勇 ...

  3. ASP&period;NET Core 中文文档 第二章 指南(4&period;4)添加 Model

    原文:Adding a model 作者:Rick Anderson 翻译:娄宇(Lyrics) 校对:许登洋(Seay).孟帅洋(书缘).姚阿勇(Mr.Yao).夏申斌 在这一节里,你将添加一些类来 ...

  4. ASP&period;NET Core 中文文档 第二章 指南(4&period;9)添加验证

    原文:Adding Validation 作者:Rick Anderson 翻译:谢炀(Kiler) 校对:孟帅洋(书缘).娄宇(Lyrics).许登洋(Seay) 在本章节中你将为 Movie 模型 ...

  5. ASP&period;NET Core 中文文档 第二章 指南 (09) 使用 Swagger 生成 ASP&period;NET Web API 在线帮助测试文档

    原文:ASP.NET Web API Help Pages using Swagger 作者:Shayne Boyer 翻译:谢炀(kiler) 翻译:许登洋(Seay) 对于开发人员来说,构建一个消 ...

  6. ASP&period;NET Core 中文文档 第二章 指南(1)用 Visual Studio Code 在 macOS 上创建首个 ASP&period;NET Core 应用程序

    原文:Your First ASP.NET Core Application on a Mac Using Visual Studio Code 作者:Daniel Roth.Steve Smith ...

  7. ASP&period;NET Core 中文文档 第二章 指南(4&period;1)ASP&period;NET Core MVC 与 Visual Studio 入门

    原文:Getting started with ASP.NET Core MVC and Visual Studio 作者:Rick Anderson 翻译:娄宇(Lyrics) 校对:刘怡(Alex ...

  8. ASP&period;NET Core 中文文档 第二章 指南(5) 在 Nano Server 上运行ASP&period;NET Core

    原文 ASP.NET Core on Nano Server 作者 Sourabh Shirhatti 翻译 娄宇(Lyrics) 校对 刘怡(AlexLEWIS).许登洋(Seay).谢炀(kile ...

  9. ASP&period;NET Core 中文文档 第二章 指南(4&period;2)添加 Controller

    原文:Adding a controller 翻译:娄宇(Lyrics) 校对:刘怡(AlexLEWIS).何镇汐.夏申斌.孟帅洋(书缘) Model-View-Controller (MVC) 架构 ...

随机推荐

  1. &period;NET 开源SqlServer ORM框架 SqlSugar 3&period;0 API

    3.1.x ,将作为3.X系统的最后一个版本,下面将会开发 全新的功能 更新列表:https://github.com/sunkaixuan/SqlSugar/releases 优点: SqlSuga ...

  2. Android之Activity之间跳转

    本人自学Android,想到什么就写点什么.主要是怕忘了,哈哈~请观者不要建议~ 今天写点Android窗口之间的跳转以及自己理解: 1.Android中窗口之间的跳转,就是Activity之间的跳转 ...

  3. php实现树状结构无级分类

    php实现树状结构无级分类   ).",'树2-1-1-2')";mysql_query($sql);?>

  4. android147 360 程序锁fragment

    package com.itheima.mobileguard.fragment; import java.util.ArrayList; import java.util.List; import ...

  5. PAT-乙级-1002&period; 写出这个数 &lpar;20&rpar;

    1002. 写出这个数 (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 读入一个自然数n,计算其各位数字 ...

  6. RBAC(Role-Based Access Control&rpar;基于角色的访问控制

    RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联.简单地说,一个用户拥有若干角色,每一个角色拥有若干权限.这样,就构造成"用 ...

  7. 使用阿里云OSS&comma;上传图片时报错:java&period;lang&period;ClassNotFoundException&colon;org&period;apache&period;http&period;ssl&period;TrustStrategy

    问题产生的原因就是jar包版本问题,阿里的SDk引入的pom中依赖的httpclient和httpcore版本高于当前项目中已经设置的版本. 解决: 删除低版本后,更新下项目.

  8. BufferedReader的小例子

    注意: BufferedReader只能接受字符流的缓冲区,因为每一个中文需要占据两个字节,所以需要将System.in这个字节输入流变为字符输入流,采用: BufferedReader buf = ...

  9. maven maven&period;compiler&period;source和maven&period;compiler&period;target的坑

    最近建议产品组把jdk 1.7升级到1.8,昨晚开发报了个问题过来,说maven.compiler.source和maven.compiler.target改成1.8之后,编译出来的代码还是1.7,如 ...

  10. codevs 3022 西天收费站

    题目描述 Description 唐僧师徒四人终于发现西天就在眼前,但猴子突然发现前面有n个收费站(如来佛太可恶),在每个收费站用不同的方式要交的钱不同,输入每个收费站的每种方法收的钱,输出最少花的钱 ...