本节用于构建一个简单的WebAPI来管理to-do列表。不会创建用户界面。
API | Description | Request body | Response body |
---|---|---|---|
GET /api/todo | Get all to-do items | None | Array of to-do items |
GET /api/todo/{id} | Get an item by ID | None | To-do item |
POST /api/todo | Add a new item | To-do item | To-do item |
PUT /api/todo/{id} | Update an existing item | To-do item | None |
DELETE /api/todo/{id} | Delete an item | None | None |
下图现实了一个应用程序的基本设计:
.客户端消费Web API,一般客户端是指移动应用程序和浏览器。本节不创建客户端,使用Postman or curl作为客户端来测试APP。
.Model表示用程序数据的对象。在这里,Model是指一个to-do item.Model表示一个C#类。也就是一个POCO(一个简单C#对象)。
.控制器是处理HTTP请求并创建HTTP响应的对象。这个程序有一个单一的控制器。
.为了简化本节教程,应用程序不使用持久性数据库。教程将使用内存存储对象。
一、先决条件
.DotNetCore 2.0 sdk 或者更高版本
.带有ASP.NET和Web开发工作负载的VS2017 版本15.3 或者或者更高版本。
二、创建项目
从VS中选择File menu ,>New>Project
选择ASP.NET Core Web Application(.net core)项目模板。项目名称"TodoApi"并选择OK.
在New ASP.NET Core Web Application - TodoApi 对话框中,选择WebAPI模板。选择OK ,不选中Enable Docker Support
启动APP
在Visual Studio中,按下CTRL+F5启动APP,VS启动浏览器并导航到http://localhost:port/api/values,其中port是随机选择端口号。浏览器显示如下:
1 | ["value1","value2"] |
创建模型类
model是一个C#对象,在app中用来展示数据,在这里model就是只一个to-do item.
添加一个Models文件夹,在解决方案中。并在文件夹中添加TodoItem类。
使用下面代码更新TodoItem类。
| namespace TodoApi.Models { public class TodoItem { public long Id { get; set; } public string Name { get; set; } public bool IsComplete { get; set; } } } |
当创建一个TodoItem数据库自动生成Id.
创建一个database context
database context是为模型提供数据的主要类配合Entity Framework.这个类继承自Microsoft.EntityFrameworkCore.DbContext。在Models文件夹下添加一个TodoContext类. 用下列代码替换
| using Microsoft.EntityFrameworkCore; namespace TodoApi.Models { public class TodoContext : DbContext { public TodoContext(DbContextOptions<TodoContext> options) : base(options) { } public DbSet<TodoItem> TodoItems { get; set; } } } |
注册一个database context
在这个步骤中,database context注册到DI容器,DI容器中注册的服务可用于控制器中。
使用内置的DI容器注册DBContext,使用下面代码:
| 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(); } } } |
上面代码:
.移除不使用的代码。
.指定一个内存数据库使用注入到service容器。
添加一个controller
在解决方案中,右击Controls文件夹,选择 Add > New Item.在Add New Item对话框中,选择Web API Controller Class 模板。为类起一个名字叫TodoController.
用下面代码替换
| 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。
.构造函数使用DI提供一个TodoContext并注入到Controller中。在Controller中DataBase context实现CRUD方法。
.如果内存数据库中没有todoItem,构造函数默认将添加一个。
获取to-do Items
对于获取一个to-do Items,添加下面代码在TodoController类中。
| [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响应显示如下:
| [ { "id": 1, "name": "Item1", "isComplete": false } ] |
路由和URL路径
[HttpGet] 特性指定一个HTTP Get方法。每个方法的URL路径构造如下:
.获取模板字符串在控制器Route特性:
namespace TodoApi.Controllers {[Route("api/[controller]")] public class TodoController : Controller{ private readonly TodoContext _context;
.用控制器的名称替换[controller],即控制器的类名减去"Controller"后缀。在这个示例中,控制器的类名是TodoController,根名是"todo"。ASP.NET 路由不区分大小写。
.如果[HttpGet]属性有一个路由模板(如[HttpGet("/products")]),将其追加到路径中..
在GetById方法中:
| [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); } |
"{id}"是todo item的ID是占位符变量,当调用GetById时,它将URL中的"{id}"的值复制给方法的id参数。
Name = "GetTodo" 创建了一个路由名称
.启动应用程序使用路由名称创建一个HTTP连接。
.在稍后文章将做解释。
返回值
GetAll方法返回一个IEnumerable。MVC自动把对象序列化成JSON,并将JSON写入的响应Body中。对这个方法的响应Code是200,假设没有未处理的异常。
相比之下GetById方法返回更一般的IActionResult类型,它表示大范围的返回类型。
GetById有两个不同的返回类型:
.如果没有Item匹配请求的ID,该方法返回404错误。返回NotFound返回一个HTTP 404响应。
.否则,该方法返回200与JSON响应正文。返回ObjectResult返回一个HTTP 200响应。
三、实现另外一些CRUD操作
Create
添加一个Create方法
| [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]指定。[FormBody]特性告诉MVC从HTTP请求的正文中获取to-do Item。
CreateAtRoute方法:
.返回201响应。HTTP 201是一个HTTP POST方法的标准的响应在服务器上创建新资源。
.添加一个Location到响应头。Location头指定了新创建的to-do item的URL。
.使用"GetTodo"命名路由来创建URL。在GetById中定义了"GetTodo"命名路由:
| [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); } |
使用Postman发送一个Create request
.设置HTTP方法为POST
.选择Body radio Button
.选择raw radio Button
.设置类型为JSON
在编辑器中输入下面JSON
| { "name":"walk dog", "isComplete":true } |
.选择Send
.选择Headers tab页
使用Location headerURI能访问新添加的Item.
Update
添加下列Update代码:
| [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(No Content). 根据HTTP规范,PUT请求需要客户端发送整个更新的实体, 而不仅是增量。要支持部分更新,请使用HTTP PATCH.
Delete
添加下面Delete方法
| [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(); } |
OK,就写到这里,下节我们将介绍使用Swagger生成ASP.NET CORE WebAPI帮助文档。
原文地址:http://www.cnblogs.com/netcoder/p/7801447.html
.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com