使用 ASP.NET Core 建立 Web API 服務
.NET Core(ASP.NET Core)與之前的 ASP.NET MVC / ASP.NET Web API 兩套不同的 Framework 不同,ASP.NET Core 中的 MVC 整合了 Web API,現在要建立 API 或 Web 都將更為簡單,因為整合後的 ASP.NET Core MVC 基於相同的程式碼與管線(pipeline)。
開發環境
ASP.NET Core 的跨平台特性,使用開發工具與開發環境的選擇相當多元。
.NET Core SDK 安裝:
安裝頁面有各平台(Windows, Linux, Mac, Docker)的安裝指南,照步驟安裝即可。
開發工具方面:
- Visual Studio 2015 Update 3 + .NET Core Tooling Preview 2 for Visual Studio 2015
- Visual Studio Code + C# for Visual Studio Code(Extensions)
使用 Windows 的開發者,地表最強的 Visual Studio 當然是最好的選擇,如果使用 MAC(Windows) 那 VS Code + C# 擴充套件後也不差。如果 Visual Studio 2015 Update 3 並安裝了最新的 .NET Core Tooling Preview 2 for Visual Studio 2015 ,那麼已包含 .NET Core SDK 的安裝。
如果 VS Code + C# 擴充套件,使用起來不是很順(例如,IntelliSense、提示加 using 等),看一下 OmniSharp Log (檢視 → 切換輸出)是否正常。重開幾次 VS Code 看看。
測試工具:
- POSTMAN
- Fiddler
兩套測試工具都行,挑喜歡的用即可。
範本工具:
安裝指令:
npm install -g yo
npm install -g generator-aspnet
這是延伸自 yeoman 的範本產生器,在不使用 Visual Studio 的情況下,它會很有幫助。
以下範例,讓我們使用 VS Code 來走一次建立 ASP.NET Core - Web API 的過程。相同的過程,使用 Visual Studio 的體驗與以前沒有太大差異,更重要的是,使用 VS Code 可以讓我們更瞭解 .NET Core 運作流程(因為要下指令),所以選擇使用指令與 VS Code 來進行實作。
ASP.NET Core - Web API 專案
我們透過 cmd.exe 下使用 yo aspnet
指令來建立 ASP.NET Core - Web API 專案。
Data Models
使用 VS Code 開啟專案資料夾,新增 Models 資料夾,新增 TodoItem
類別。
透過 VS Code 新增的檔案內容都是空白,這對記憶力是個不小的考驗。建立檔案這件事,generator-aspnet 也有想到。
yo aspnet:Class TodoItem
namespace corewebapi.Models { public class TodoItem { public string Key { get; set; } public string Name { get; set; } public bool IsComplete { get; set; } } }
加入 Repository 類別
此範例沒有使用資料庫,我們使用 Repository 來進行資料層的封裝。
yo aspnet:Interface ITodoRepository
加前 CURD 對應的方法介面:
namespace corewebapi.Models { public interface ITodoRepository { void Add(TodoItem item); IEnumerable<TodoItem> GetAll(); TodoItem Find(string key); TodoItem Remove(string key); void Update(TodoItem item); } }
新增 TodoRepository 類別以實作介面:
yo aspnet:Class TodoRepository
TodoRepository 類別:
namespace corewebapi.Models { public class TodoRepository : ITodoRepository { private static ConcurrentDictionary<string, TodoItem> _todos = new ConcurrentDictionary<string, TodoItem>(); public TodoRepository() { Add(new TodoItem { Name = "Item1"}); } 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 IEnumerable<TodoItem> GetAll() { return _todos.Values; } 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
ASP.NET Core 內建 DI (dependency injection) 機制,讓我們能在 Controller 被初始化時進行注入作業,使用 DI 之後,可大幅提升應用程式的可測試性。
我們要註冊 Repository 到 DI 容器中。開啟 Startup.cs ,先 Models 的參考:
using corewebapi.Models;
在 ConfigureServices
方法加入以下程式碼:
public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddMvc(); // 註冊 repository 型別 services.AddSingleton<ITodoRepository, TodoRepository>(); }
dotnet 指令
.NET Core SDK 新增 dotnet
指令,讓我們可以新增專案、套件還原、專案建置、發行專案、執行專案、測試專案,封裝為NuGet套件等。
dotnet
的新增專案會新增一個 Console - Hello World 專案,要改到能執行 ASP.NET Core 需要一些設置,所以我們選擇 yeoman 來快速建立範本。
dotnet -h
可以查詢指令相關參數。
.NET Command Line Tools (1.0.0-preview2-003121)
Usage: dotnet [host-options] [command] [arguments] [common-options]
Arguments:
[command] The command to execute
[arguments] Arguments to pass to the command
[host-options] Options specific to dotnet (host)
[common-options] Options common to all commands
Common options:
-v|--verbose Enable verbose output
-h|--help Show help
Host options (passed before the command):
-v|--verbose Enable verbose output
--version Display .NET CLI Version Number
--info Display .NET CLI Info
Common Commands:
new Initialize a basic .NET project
restore Restore dependencies specified in the .NET project
build Builds a .NET project
publish Publishes a .NET project for deployment (including the runtime)
run Compiles and immediately executes a .NET project
test Runs unit tests using the test runner specified in the project
pack Creates a NuGet package
依下面順序輸入執行:
dotnet restore
dotnet build
建置過程如果有錯誤,請依錯誤訊息進行排除。
記得在執行
dotnet build
之前,確定所有檔案已經存檔,筆者有好幾次都忘了存檔,然後跑不出正確結果,查程式碼查了半天又查不出來。想要怪東怪西時才發現自己是豬頭。
新增 Controller
在 Controllers 目錄下新增 TodoController:
yo aspnet:WebApiController TodoController
移除預設 API Action 程式碼,替換為下列程式碼:
namespace corewebapi.Controllers { [Route("api/[controller]")] public class TodoController : Controller { public TodoController(ITodoRepository todoItems) { TodoItems = todoItems; } public ITodoRepository TodoItems { get; set; } } }
這裡先定義一個空的 Controller,TodoItems 會透過前面定義的 DI 進行注入作業。
取得 Todo 清單
依照下列程式碼,可以取得 Todo 清單:
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); }
由屬性 [HttpGet]
與命名 GetXXX 可以得知,這些方法實作 HTTP Get 方法,透過 dotnet run
可以把 ASP.NET Core 專案執行起來,預設位置是
http://localhost:5000,進行 Get 方法測試:
ObjectResult
GetAll
回傳一個 CLR 物件,ASP.NET Core MVC 自動序列化物件為 JSON 並將 JSON 寫入回應訊息的 Body 之中。
GetById
需回傳一個 IActionResult
型別,因為 GetById
有兩種不同的回傳型別的選擇。
- 如果找不到對應的
id
,方法會回傳 404 狀態(NotFound). - 如果成功,
ObjectResult
回傳 200 狀態並回 JSON 寫入 Body 回傳。
ObjectResult 的繼承關係:
public class ObjectResult : ActionResult, IActionResult
完成CUD實作
前面我們完成 Read 的實作,現在往下進行 Create、Update、Delete 相關實作。
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); }
CreatedAtRoute
會建立一個狀態 201 的回應,這是為了符合 HTTP 的標準,也就為通知 Client 端新增資源位於那個位置。
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 標準要回傳狀態 204(No Content)。PUT 方法需要傳遞完整的 Update 實體,如果是部分更新,使用 HTTP PATCH。
Delete
[HttpDelete("{id}")] public void Delete(string id) { TodoItems.Remove(id); }
void 回傳 狀態 204(No Content),意思是,Client 收到 204 事件代表資源已經刪除或不存在。
所以有二個方向來思考:
- Delete 意思是"刪除已存在的資源",如果不存在,回傳狀態 404。
- Delete 意思是"確定 item 不在集合裡",如果 item 不存在集合,回傳狀態 204。
小結
以上的實例,故意沒有使用 Visual Studio / IIS Express 等常用的開發工具,使用 VS Code + C# + yo + dotnet 一樣可以開發與執行 ASP.NET Core Web API 服務。如果你覺得打 dotnet 指令太麻煩,VS Code 的偵錯,一樣可下中斷點,可以啟動 ASP.NET Core 都沒問題。
K大您好,請問一下,我是MAC使用者
回覆刪除npm install -g yo
npm install -g generator-aspnet
這兩行指令我應該下在哪裡才會執行??
首先你要先安裝 nodejs, 然後在 terminal 下那些指令即可。
回覆刪除