原文:Building Your First Web API with ASP.NET Core MVC and Visual Studio
作者:Mike Wasson 和 Rick 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

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

  • 不管是哪个调用 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

在 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 路径

[HttpGet] 标签指定这些方法均为 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 设置

了解更多有关请求路由的信息请参考路由到控制器 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/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 操作

最后一步是 CreateUpdate 以及 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 方法,用 [HttpPost] 标签声明。[FromBody] 标签告诉 MVC 从 HTTP 请求的正文中获取 to-do 项的值。

当通过 CreatedAtRoute 方法向服务器发出 HTTP POST 方法以创建新资源时,将返回标准的 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

这是一个简单的 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。响应是 204 (No Content)。根据 HTTP 规范,PUT 请求要求客户端发送整个实体更新,而不仅仅是增量。为了支持局部更新,请使用 HTTP PATCH。

Delete

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

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

  • "Delete" 代表「删除一个已存在的项」,如果不存在返回 404。

  • "Delete" 代表「确保该项不在集合中」,如果项目不在集合中返回 204。

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

下一步

  • 关于如何为原生移动 App 创建后端, 请参考为原生移动应用创建后台服务。

  • 更多关于 API 部署的问题, 请参考发布与部署。

  • 查看或者下载示例代码

相关文章:

  • ASP.NET Core 1.0 入门——了解一个空项目

  • ASP.NET Core 1.0 部署 HTTPS (.NET Framework 4.5.1)

  • .NET Core 1.0、ASP.NET Core 1.0和EF Core 1.0简介

  • 云服务器下ASP.NET Core 1.0环境搭建(包含mono与coreclr)

  • 使用VS Code开发ASP.NET Core 应用程序

  • dotnet run是如何启动asp.net core站点的

  • ASP.NET Core提供模块化Middleware组件

  • “dotnet restore"和"dotnet run"都做了些什么?

  • 探秘 dotnet run 如何运行 .NET Core 应用程序

  • .NET Portability Analyzer 已开源

  • ASP.NET Core的配置(1):读取配置信息

  • ASP.NET Core的配置(2):配置模型详解

  • .NET Core 1.0 RC2 历险之旅

  • 使用VS Code开发 调试.NET Core 应用程序

  • 让我们Core在一起:ASP.NET Core & .NET Core

  • .NET Core VS Code 环境配置

  • 官方博客明确了 .NET Core RC2/RTM 时间表

  • .NET Core全新的配置管理[共9篇]

  • 利用记事本创建一个ASP.NET Core RC2 MVC应用

  • 微软.NET 正式劈腿成功,横跨所有平台

  • .NET Core 1.0 CentOS7 尝试

  • 解读发布:.NET Core RC2 and .NET Core SDK Preview 1

  • [.NET Core].NET Core R2安装及示例教程

  • ASP.NET Core 开发-中间件(Middleware)

  • 结合Jexus + Kestrel 部署 asp.net core 生产环境

  • 通过Jexus 部署 dotnetcore版本MusicStore 示例程序

  • ASP.NET Core 中文文档 第一章 入门

  • 用 Visual Studio Code 在 macOS 上创建首个 ASP.NET Core 应用程序

原文地址:http://www.cnblogs.com/dotNETCoreSG/p/aspnetcore-2_2-first-web-api.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

赞赏

人赞赏

用 Visual Studio 和 ASP.NET Core MVC 创建首个 Web API相关推荐

  1. 在ASP.NET Core MVC中构建简单 Web Api

    Getting Started 在 ASP.NET Core MVC 框架中,ASP.NET 团队为我们提供了一整套的用于构建一个 Web 中的各种部分所需的套件,那么有些时候我们只需要做一个简单的 ...

  2. Visual Studio 2017 ASP.NET Core开发

    Visual Studio 2017 ASP.NET Core开发,Visual Studio 2017 已经内置ASP.NET Core 开发工具. 在选择.NET Core 功能安装以后就可以进行 ...

  3. 使用Http-Repl工具测试ASP.NET Core 2.2中的Web Api项目

    今天,Visual Studio中没有内置工具来测试WEB API.使用浏览器,只能测试http GET请求.您需要使用Postman,SoapUI,Fiddler或Swagger等第三方工具来执行W ...

  4. 【视频教程】使用 ASP.NET Core 3.x 构建 RESTful Web API 已完结

    使用 ASP.NET Core 3.x 构建 RESTful Web API 的视频教程已经完结,共50讲,约10.5小时. B站可看,点击原文链接. 度娘盘可下载完整视频: https://pan. ...

  5. ASP.NET Core 3.1 系列之 Web API 添加身份验证Jwt

    ASP.NET Core 3.1 系列之 Web API 中间件篇 (一) 身份验证(Jwt)中间件使用步骤 添加 NuGet程序包 添加包:Microsoft.AspNetCore.Authenti ...

  6. 使用静态基类方案让 ASP.NET Core 实现遵循 HATEOAS Restful Web API

    Hypermedia As The Engine Of Application State (HATEOAS) HATEOAS(Hypermedia as the engine of applicat ...

  7. ASP.NET Core MVC 与 Visual Studio 入门

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

  8. ASP.NET Core 进程外(out-of-process)托管(7)《从零开始学ASP.NET CORE MVC》

    本文出自<从零开始学ASP.NET CORE MVC> 推荐文章:ASP.NET Core 进程内(InProcess)托管 ASP.NET Core 进程内(InProcess)托管 我 ...

  9. 使用ASP.NET Core MVC的Vue.Js

    目录 内容主题 VUE.JS简介 DOT NET Core 下载和安装Visual Studio 2017 ASP.NET Core Spa模板 基础知识和设置 Node.js 节点包管理(NPM) ...

最新文章

  1. 从外部导入django模块
  2. CCNA11月14日战报
  3. 错误解决 :Microsoft Visual C++ 14.0 is require Microsoft Visual C++ Builder 包丢失或者损坏
  4. 《CODM》的成功源自何处?TGA年度移动游戏的总结和思考
  5. python编程入门第九讲,第九讲作业---函数
  6. 交换机出现电源故障怎么解决?
  7. 远程连接oracle无监听
  8. android登陆的编写
  9. 掌握这8个CSS开发工具让你瞬间成为开发高手
  10. android没有蓝牙设备,【Android】没有触发LeScanCallback导致无法搜索到蓝牙设备
  11. 我也不知道取什么标题好了!
  12. java链式语法_javaScript链式调用原理以及加法实现
  13. 【Axure】Axure RP 9 下载、短期试用破解安装和汉化步骤 —— 可供安装参考,短期试用,目前授权码已逐渐失效
  14. 计算机多媒体技术广泛应用于各个领域,计算机多媒体技术的现状及发展前景
  15. 纯css单击事件,纯css实现点击事件
  16. 云闪付华为P9指纹_华为云闪付app下载-华为云闪付 安卓版v9.0.11.301-PC6安卓网
  17. 把桌面路径改到D盘,忘记新建文件夹,D盘所有文件跑到桌面怎么办?
  18. centos xfs硬盘扩容
  19. HFUT雨课堂形式与政策【支持考试】
  20. 手把手教你React Native接入聊天IM即时通讯功能-源码分享

热门文章

  1. android进程间通信:使用AIDL
  2. Eclipse/Myeclipse生成serialVersionUID方法
  3. windows server 2012 dhcp 配置故障转移
  4. 【POJ】【最小生成树】1789 Truck History
  5. 云计算的关键特点及挑战
  6. C# 异步方法的异常处理
  7. MASA Framework - 整体设计思路
  8. .NET 现代化动态 LINQ 库 Gridify
  9. c# 弹性和瞬态故障处理库Polly
  10. 用啥Selenium?! .NET程序员就用自家的Playwright for .NET