[Day21] C# MVC RESTful API (下) 實作RESTful API - C#&AspNetCore

在上回中我們介紹了 [Day20] C# MVC RESTful API (中) 建立API專案 - C#&AspNetCore ,我們在原本的MVC專案中加入了WEB API專案。

而這回將會撰寫RESTful API!
本文會以:https://docs.microsoft.com/zh-tw/aspnet/core/tutorials/first-web-api?view=aspnetcore-3.1&tabs=visual-studio 提供的範例作為實作依據。

RESTful API規格

方法 網址 描述 要求文本 回應文本
GET /api/todo 取得所有待辦事項 待辦事項陣列
GET /api/todo/{id} 依識別碼取得待辦事項 待辦事項
POST /api/todo 新增待辦事項 待辦事項 待辦事項
PUT /api/todo/{id} 更新現有的待辦事項 待辦事項 待辦事項
DELETE /api/todo/{id} 刪除待辦事項 待辦事項

實作RESTful API

先安裝基本資料庫套件
1.Microsoft.EntityFrameworkCore

2.Microsoft.EntityFrameworkCore.SqlServer

3.Microsoft.EntityFrameworkCore.Tools

4.使用DB First

Scaffold-DbContext指令,來還原TodoDB資料庫的Models

1
Scaffold-DbContext "Server=.\SQLExpress;Database=TodoDB;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models

執行畫面:

執行後:

5.Startup.cs增加資料庫配置

1
2
3
4
5
6
7
8
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
// 資料庫配置
var connection = @"Server=.\SQLExpress;Database=TodoDB;Trusted_Connection=True;ConnectRetryCount=0";
services.AddDbContext<TodoDBContext>(options => options.UseSqlServer(connection));
}

6.撰寫RESTful API

~/Controllers/TodoController.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using TodoAPI.Models;

namespace TodoAPI.Controllers
{

[Route("api/[controller]")]
[ApiController]
public class TodoController : ControllerBase
{
private readonly TodoDBContext _context;
public TodoController(TodoDBContext context)
{
_context = context;
}
[HttpGet]
public async Task<ActionResult<IEnumerable<Todo>>> GetTodos()
{
return await _context.Todos.Where(x=>x.IsDeleted != 1).ToListAsync();
}

[HttpGet("{id}")]
public async Task<ActionResult<Todo>> GetTodo(int id)
{
var obj = await _context.Todos.FindAsync(id);

if (obj.IsDeleted == 1)
{
return NotFound();
}

return obj;
}

[HttpPut("{id}")]
public async Task<ActionResult<Todo>> PutTodo(int id, Todo newObj)
{
if (id != newObj.Id)
{
return BadRequest();
}

var obj = await _context.Todos.FindAsync(id);

if(obj.IsDeleted == 1)
{
return NotFound();
}

obj.IsComplete = newObj.IsComplete;
obj.Name = newObj.Name;

try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!TodoExists(id))
{
return NotFound();
}
else
{
throw;
}
}

return obj;
}

[HttpPost]
public async Task<ActionResult<Todo>> PostTodo(Todo newObj)
{
var obj = new Todo
{
Name = newObj.Name,
IsComplete = 0,
IsDeleted = 0
};
_context.Todos.Add(obj);
await _context.SaveChangesAsync();

return CreatedAtAction(nameof(GetTodo), new { id = obj.Id }, obj);
}
[HttpDelete("{id}")]
public async Task<ActionResult<Todo>> DeleteTodo(int id)
{
var obj = await _context.Todos.FindAsync(id);
obj.IsDeleted = 1;

if (obj == null)
{
return NotFound();
}
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!TodoExists(id))
{
return NotFound();
}
else
{
throw;
}
}

return obj;
}

private bool TodoExists(int id)
{
return _context.Todos.Any(e => e.Id == id);
}
}
}

7.用postman測試

專案程式碼:
https://github.com/yuhsiang237/ASP.NET-Core-RESTfulAPI

總結

這樣就完成了RESTful API了!

參考資料
https://docs.microsoft.com/zh-tw/aspnet/core/tutorials/first-web-api?view=aspnetcore-3.1&tabs=visual-studio