1. 程式人生 > >ASP.NET Core 中文文件 第二章 指南(2)用 Visual Studio 和 ASP.NET Core MVC 建立首個 Web API

ASP.NET Core 中文文件 第二章 指南(2)用 Visual Studio 和 ASP.NET Core MVC 建立首個 Web API

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 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 響應。

路由和 URL 路徑

[HttpGet] 特性標明這些方法支援 HTTP GET,對 controller 中的方法標註 url 路徑,有以下步驟:

  • 在 controller 特性中標註模板:[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" 的啟動 Url

  • 右擊專案 > Properties
  • 選擇 Debug 選項卡,將 Launch URL 的值設定為 api/todo

返回值

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/todoport 是一個隨機數。如果你使用 Chrome、Edge 或者 Firefox 瀏覽器,todo 資料將會被顯示。如果你使用 IE,IE 將會彈出視窗提示要求開啟或者儲存 todo.json 檔案。

啟動 Fiddler,從 File 選單,取消選擇 Capture Traffic 選項。這個會關閉捕獲 HTTP traffic。

選擇 Composer 頁面。在 Parsed 選項卡中,輸入 http://localhost:port/api/todoport 是實際的埠號。點選 Execute 傳送請求。

結果會顯示在 sessions 列表中,響應碼是200。使用 Inspectors 選項卡來檢視響應內容,包括請求正文。

實現其他的 CRUD 操作

最後一步是為 Controller 增加 CreateUpdate 以及 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);
}

這是一個 HTTP POST 方法,用 [HttpPost] 特性宣告。[FromBody] 特性告訴 MVC 從 HTTP 請求的正文中獲取 to-do 項的值。

當通過客戶端向伺服器發出 POST 請求來建立新資源時,CreatedAtRoute 方法將返回標準的 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.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}

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 錯誤,客戶端將需要處理這種情況。

下一步

返回目錄

相關推薦

ASP.NET Core 中文 第二 指南2 Visual Studio ASP.NET Core MVC 建立 Web API

HTTP 協議不僅僅提供網頁服務。它也是一個構建公開服務和資料 API 的強大平臺。HTTP 協議是簡單、靈活、無處不在的。幾乎你能想到的任何平臺上都有 HTTP 支援,所以 HTTP 服務能夠傳送到多種客戶端, 包括瀏覽器,移動裝置和傳統的桌面應用程式。 在本教程中,你將建立一個簡單的 Web API 來

ASP.NET Core 中文 第二 指南1 Visual Studio Code 在 macOS 上建立 ASP.NET Core 應用程式

本文已更新,最後更新於2017年4月28日 聯絡我們: QQ Group: 436035237 (dotNet Core Studying Group) GitHub Repo: https://github.com/dotnetcore/aspnetcore-doc-cn/ 以下為老翻譯存檔 本節將

ASP.NET Core 中文 第二 指南3 Visual Studio 釋出一個 Azure 雲 Web 應用程式

設定開發環境 注意 如果你的機器之前任何依賴都沒有安裝過,SDK 的安裝時間將會超過30分鐘。 建立一個 Web 應用程式 在 Visual Studio 的 Start 頁面,點選 New Project。 另外,你也可以通過選單新建專案。點選 File > New > Proje

ASP.NET Core 中文 第二 指南8 使用 dotnet watch 開發 ASP.NET Core 應用程式

本文已更新,最後更新於2017年4月27日 以下為老翻譯存檔 介紹 dotnet watch 是一個開發階段在原始檔發生變動的情況下使用 dotnet 命令的工具。 當代碼發生變動的時候可以用來執行編譯,執行測試,或者釋出操作。 在本教程中,我們將使用一個現有的計算兩個數字之和以及乘積的 WebAp

ASP.NET Core 中文 第二 指南 09 使用 Swagger 生成 ASP.NET Web API 線上幫助測試

對於開發人員來說,構建一個消費應用程式時去了解各種各樣的 API 是一個巨大的挑戰。 在你的 Web API 專案中使用 Swagger 的 .NET Core 封裝 Swashbuckle 可以幫助你建立良好的文件和幫助頁面。 Swashbuckle 可以通過修改 Startup.cs 作為一組 NuGe

ASP.NET Core 中文 第二 指南5 在 Nano Server 上執行ASP.NET Core

注意:本教程使用 Windows Server Technical Preview 5 的預發行版本的 Nano Server 安裝選項。 你可以在虛擬硬碟映像中用來內部演示和評估,但不能在生產環境中使用該軟體。可通過 https://go.microsoft.com/fwlink/?LinkId=624

ASP.NET Core 中文 第二 指南4.10檢查自動生成的Detail方法Delete方法

開啟 Movie 控制器並檢視 Details 方法: // GET: Movies/Details/5 public async Task<IActionResult> Details(int? id) { if (id == null) { return No

ASP.NET Core 中文 第二 指南4.1ASP.NET Core MVCVisual Studio 入門

這篇教程將告訴你如何使用 Visual Studio 2015 構建一個 ASP.NET Core MVC Web 應用程式的基礎知識。 安裝 Visual Studio 和 .NET Core 安裝 Visual Studio Community 2015。選擇 Community 下載並執行預設安裝

ASP.NET Core 中文 第二 指南4.6Controller 方法與檢視

我們已經初步的建立了一個 movie 應用程式,但是展示並不理想。我們不希望看到 release date 欄位顯示時間並且 ReleaseDate 應該是兩個單詞。 開啟 Models/Movie.cs 檔案並新增下面高亮的程式碼行: public class Movie { public in

ASP.NET Core 中文 第二 指南4.5使用 SQL Server LocalDB

ApplicationDbContext 類負責連線資料庫並將 Movie 物件和資料記錄進行對映。 Startup.cs 檔案中,資料庫上下文是在 ConfigureServices 方法中用 Dependency Injection 容器進行註冊的。 // This method gets called

python之的讀寫2

import 文件讀寫 哈哈 進入 imp std 技術 都是 繼續 小R昨天因為在研究weblogic的漏洞就沒來得及學習python(好吧,這都是借口,懶了,大家可不能像我這樣。要堅持每天都學)。 這個進度是有點慢呀。哎呀,沒事沒事,我還年輕,才20歲。 哈哈,玩

Java EE入門教程系列第二JSP——JSP標準標籤自定義標籤的配置與使用

2.6 JSP的標籤 2.6.1 標籤簡介 標籤就是把一段具體業務的Java程式碼封裝起來,然後以標記語言的形式在頁面檔案中對它進行呼叫,增強頁面檔案和Java程式的獨立性。 目前標籤庫有兩種形式:標準標籤庫和自定義標籤。 JSP標準標籤(JSTL)是一個可以實現We

的相似度2--最小雜湊簽名

           接著上一篇的部落格繼續下去,這篇部落格主要講下最小雜湊簽名的東西。           對於上篇部落格中提到的shingle,可以說是在壓縮資料量的基礎上又儘可能保留了源文件的特徵,以便於後面對不同的文件進行相似度比較。但是我們會發現,shingle集

ASP.NET Core 中文 第四 MVC4.6Areas區域

Areas 是 ASP.NET MVC 用來將相關功能組織成一組單獨名稱空間(路由)和資料夾結構(檢視)的功能。使用 Areas 建立層次結構的路由,是通過新增另一個路由引數 area 到 Controller 和 action。 Areas 提供了一種把大型 ASP.NET Core MVC Web 應用

ASP.NET Core 中文 第五 測試5.2整合測試

整合測試確保應用程式的元件組裝在一起時正常工作。 ASP.NET Core支援使用單元測試框架和可用於處理沒有網路開銷請求的內建測試的網路主機整合測試。 章節: 整合測試介紹 整合測試驗證應用程式不同的部位是否正確地組裝在一起。不像單元測試,整合測試經常涉及到應用基礎設施,如資料庫,檔案系統,網路資源

ASP.NET Core 中文 第四 MVC4.2控制器操作的路由

ASP.NET Core MVC 使用路由 中介軟體 來匹配傳入請求的 URL 並對映到具體的操作。路由通過啟動程式碼或者特性定義。路由描述 URL 路徑應該如何匹配到操作。路由也同樣用於生成響應中返回的 URL(用於連結)。 這篇文章將解釋 MVC 和路由之間的相互作用,以及典型的 MVC 應用程式如何使

ASP.NET Core 中文 第四 MVC4.1Controllers, Actions Action Results

Action 和 action result 是開發者使用 ASP.NET MVC 構建應用程式的基礎部分。 什麼是 Controller 在 ASP.NET MVC 中, 控制器( Controller  )用於定義和聚合操作(Action)的一個集合。操作( 或操作方法 )是控制器中處理入站請求的一個方

ASP.NET Core 中文 第四 MVC2.3格式化響應資料

ASP.NET Core MVC 內建支援對相應資料(response data)的格式化,用來修正格式或生成客戶端指定的格式。 特定格式的操作結果 某些操作結果(Action result)的型別是指定的特定格式,比如 JsonResult 或 ContentResult。Action 可以返回格式化為

ASP.NET Core 中文 第四 MVC4.4依賴注入控制器

ASP.NET Core MVC 控制器應通過它們的構造器明確的請求它們的依賴關係。在某些情況下,單個控制器的操作可能需要一個服務,在控制器級別上的請求可能沒有意義。在這種情況下,你也可以選擇將服務作為 action 方法的引數。 章節: 依賴注入 依賴注入(Dependency injection,

ASP.NET Core 中文 第四 MVC01ASP.NET Core MVC 概覽

ASP.NET Core MVC 是使用模型-檢視-控制器(Model-View-Controller)設計模式構建網頁應用與 API 的豐富的框架。 什麼是 MVC 模式? 模型-檢視-控制器(MVC)架構模式將一個應用區分為三部分主要元件:模型、檢視、與控制器。這種模式有助實現關注分離。使用這種模式,使