标签:获取 rem oid http get size 生成 date interface inject
小分享:我有几张阿里云优惠券,用券购买或者升级阿里云相应产品最多可以优惠五折!领券地址:https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=ohmepe03
原文: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 | 无 | 无 |
下面的图表展示了应用程序的基本设计:
我们不创建客户端,我们使用 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 项,添加下列方法到 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 响应。
[HttpGet] 特性标明这些方法支持 HTTP GET,对 controller 中的方法标注 url 路径,有以下步骤:
[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
:了解更多有关请求路由的信息请参考路由到控制器 Action。
GetAll
方法返回 CLR 对象。MVC 自动把对象序列化为 JSON 并把 JSON 对象写入响应消息正文。响应状态码为 200,假设没有未处理异常的情况下。(未处理异常一般会被转化为 5xx 错误。)
相反,GetById
将会返回 IActionResult
类型,它代表了更加通用的结果对象。因为 GetById
有两个不同的返回值:
这一步是可选的,但是有助于我们查看 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 选项卡来查看响应内容,包括请求正文。
最后一步是为 Controller 增加 Create
、Update
以及 Delete
这三个方法。这些方法都是围绕着一个主题,所以我将只列出代码以及标注出主要的区别。
[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 来创建和发送一个请求:
Content-Type: application/json
,意思是 Content-Type
类型的头信息值为 application/json
。Fiddler 会自动添加 Content-Length 头信息。{"Name":"<你的 to-do 项目>"}
这是一个简单的 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}
[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。
[HttpDelete("{id}")]
public void Delete(string id)
{
TodoItems.Remove(id);
}
方法返回 204 (无内容) 响应。这意味着客户端会收到 204 响应即使该项目已被删除,或者根本不存在。有两种方法来处理请求删除不存在资源的问题:
无论哪种方法是合理的。如果收到 404 错误,客户端将需要处理这种情况。
参考页面:http://qingqingquege.cnblogs.com/p/5933752.html
第二章 指南(2)用 Visual Studio 和 ASP.NET Core MVC 创建首个 Web API
标签:获取 rem oid http get size 生成 date interface inject
原文地址:http://www.cnblogs.com/wufei999/p/6758734.html