用 Visual Studio 和 ASP.NET Core MVC 创建首个 Web API
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用 Visual Studio 和 ASP.NET Core MVC 创建首个 Web API相关的知识,希望对你有一定的参考价值。
HTTP 协议不仅仅提供网页服务。它也是一个构建公开服务和数据 API 的强大平台。HTTP 协议是简单、灵活、无处不在的。几乎你能想到的任何平台上都有 HTTP 支持,所以 HTTP 服务能够发送到多种客户端, 包括浏览器,移动设备和传统的桌面应用程序。
在本教程中,你将创建一个简单的 Web API 来管理一个 "to-do" 列表。在本教程中你无需编写任何 UI 代码。
ASP.NET Core 已经内置了用 MVC 架构 构建 Web API 的支持。统一了两个框架使得它易于构建应用程序,包括用户界面(html)和 API,因为现在它们共享相同的代码库和管道。
注意
如果你想把一个老的 Web API 应用程序迁移到 ASP.NET Core, 参考
总览
这是你需要创建的 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 | 无 | 无 |
下面的图表展示了应用程序的基本设计:
不管是哪个调用 API 的客户端(浏览器、移动应用等)。我们不会在本教程编写客户端。
model 是一个代表你应用程序数据的类。在本案例中,只有一个模型 to-do 项。模型表现为简单 C# 类型 (POCOs),
controller 是一个处理 HTTP 请求并返回 HTTP 响应的对象。这个示例程序将只会有一个 controller。
为了保证教程简单我们不使用数据库。作为替代,我们会把 to-do 项存入内存。但是我们依然包含了一个数据访问层(不重要的),用来隔离 Web API和数据层。如果想使用数据库,参考。
安装 Fiddler
我们不创建客户端,我们使用 来测试 API。Fiddler 是一个 Web 调试工具可以让您撰写的 HTTP 请求进行发送并查看原始的 HTTP 响应。
创建项目
启动 Visual Studio。从 File 菜单, 选择 New > Project。
选择 ASP.NET Core Web Application 项目模版。项目命名为 TodoApi
并且点击 OK。
在 New ASP.NET Core Web Application (.NET Core) - TodoApi 对话框中,选择 Web API 模版。点击 OK。
添加模型类
模型表示应用程序中的数据的对象。在本示例中,唯一使用到的模型是一个 to-do 项。
添加一个名为 "Models" 的目录。在解决方案浏览器中, 右击项目。选择 Add > New Folder。把目录名命名为 Models。
注意
你可以把模型类放到项目的任何地方,但是 Models 是约定的默认目录。
下一步,添加一个 TodoItem
类。右击 Models 目录并选择 Add > New Item。
在 Add New Item 对话框中,选择 Class 模版。命名类为 TodoItem
并点击 OK。
将生成代码替换为:
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 OKContent-Type: application/json; charset=utf-8Server: Microsoft-IIS/10.0Date: Thu, 18 Jun 2015 20:51:10 GMTContent-Length: 82[{"Key":"4f67d7c5-a2a9-4aae-b030-16003dd829ae","Name":"Item1","IsComplete":false}]
在后面的教程中,我将会告诉你如何使用 Fiddler 工具查看 HTTP 响应。
路由和 URL 路径
标签指定这些方法均为 HTTP GET 方法。每个方法构建的 Url 如下:
替换 controller 模版里面的路由标签,
[Route("api/[controller]")]
把 "[Controller]" 替换为控制器名,必须是带 "Controller" 后缀的小写名称。在本示例里面控制器的名字为 "todo"(不区分大小写)。对于这个例子,controller 的类名是 TodoController 并且根名是 "todo"。ASP.NET MVC Core 是需要区分大小写的。
如果
[HttpGet]
标签有模版字符串,附加到路径。本示例没有模版字符串。
对于 GetById
方法,在实际的 HTTP 请求中 "{id}" 是一个占位符,客户端在运行时会使用 todo
项的 ID 属性,当 MVC 调用 GetById
,会把 "{id}" 占位符分配到 Url 方法的 id
参数上去。
更换 "api/todo" 的启动 Url
右击项目 > Properties
选择 Debug 选项卡变更 "api/todo" Launch URL 设置
了解更多有关请求路由的信息请参考。
返回值
GetAll
方法返回一个 CLR 对象。MVC 自动把对象序列化为 并把 JSON 对象写入响应消息正文。响应状态码为 200,假设没有未处理异常的情况下。(未处理异常一般会被转化为 5xx 错误。)
相反,GetById
将会返回一个 IActionResult
类型,代表一个更加通用的结果对象。因为 GetById
有两个不同的返回值:
如果没有数据项可以匹配 ID,方法会返回 404 错误,并最终以返回 NotFound 告终。
否则方法会返回 200 以及 JSON 响应正文。并最终以返回 告终。
使用 Fiddler 调用 API
这一步是可选的,但是有助于我们查看 Web API 返回的原始 HTTP 响应。
在 Visual Studio 中,点击 ^F5
启动项目。Visual Studio 启动浏览器并导航到 http://localhost:port/api/todo
,port 是一个随机数。如果你使用 Chrome、Edge 或者 Firefox 浏览器,todo 数据将会被显示。如果你使用 IE,IE 将会弹出窗口提示要求打开或者保存 todo.json 文件。
启动 Fiddler,从 File 菜单,取消选择 Capture Traffic 选项。这个会关闭捕获 HTTP traffic。
选择 Composer 页面。在 Parsed 选项卡中,输入 http://localhost:port/api/todo
,port 是实际的端口号。点击 Execute 发送请求。
结果会显示在 sessions 列表中,响应码是200。使用 Inspectors 选项卡来查看响应内容,包括请求正文。
实现其他的 CRUD 操作
最后一步是 Create
、Update
以及 Delete
方法到 Controller。这些方法都是围绕着一个主题,所以我将只列出代码以及标注出主要的区别。
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 方法,用 标签声明。 标签告诉 MVC 从 HTTP 请求的正文中获取 to-do 项的值。
当通过 方法向服务器发出 HTTP POST 方法以创建新资源时,将返回标准的 201 响应。CreateAtRoute
还把 Location 头信息加入到了响应。Location 头信息指定新创建的 todo 项的 URI。查看 。
我们使用 Fiddler 来创建和发送一个请求:
在 Composer 页面,从下拉框选择 POST。
在请求头的文本框中, 添加
Content-Type: application/json
,意思是Content-Type
类型的头信息值为application/json
。Fiddler 会自动添加 Content-Length 头信息。在请求正文的文本框,输入以下内容:
{"Name":"<你的 to-do 项目>"}
点击 Execute。
这是一个简单的 HTTP 会话. 使用 Raw 选项卡查看会话数据.
Request:
POST http://localhost:29359/api/todo HTTP/1.1User-Agent: FiddlerHost: localhost:29359Content-Type: application/jsonContent-Length: 33{"Name":"Alphabetize paperclips"}
Response:
HTTP/1.1 201 CreatedContent-Type: application/json; charset=utf-8Location: http://localhost:29359/api/Todo/8fa2154d-f862-41f8-a5e5-a9a3faba0233Server: Microsoft-IIS/10.0Date: Thu, 18 Jun 2015 20:51:55 GMTContent-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。响应是 。根据 HTTP 规范,PUT 请求要求客户端发送整个实体更新,而不仅仅是增量。为了支持局部更新,请使用 HTTP PATCH。
Delete
[HttpDelete("{id}")]
public void Delete(string id){
TodoItems.Remove(id);
}
方法返回 204 (无内容) 响应。这意味着客户端会收到 204 响应即使该项目已被删除,或者根本不存在。有两种方法来处理请求删除不存在资源的问题:
"Delete" 代表「删除一个已存在的项」,如果不存在返回 404。
"Delete" 代表「确保该项不在集合中」,如果项目不在集合中返回 204。
无论哪种方法是合理的。如果收到 404 错误,客户端将需要处理这种情况。
下一步
关于如何为原生移动 App 创建后端, 请参考。
更多关于 API 部署的问题, 请参考。
相关文章:
.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注
以上是关于用 Visual Studio 和 ASP.NET Core MVC 创建首个 Web API的主要内容,如果未能解决你的问题,请参考以下文章
第二章 指南用 Visual Studio 和 ASP.NET Core MVC 创建首个 Web API
集成用两个不同 Visual Studio 版本编写的 ASP.NET 项目的最佳方式
ASP.Net - 从 Visual Studio 2003 过渡到 Visual Studio 2010
ASP.NET Core 中文文档 第二章 指南用 Visual Studio 发布一个 Azure