練習 - 新增控制器
控制器是具有一或多個稱為動作之公用方法的公用類別。 依照慣例,控制器會放在專案根目錄的 Controllers 目錄中。 動作會公開為 Web API 控制器內的 HTTP 端點。
建立控制器
選取 Visual Studio Code 中的 Controllers 資料夾,然後新增名為 PizzaController.cs 的新檔案。
在 Controllers 目錄中會建立名為 PizzaController.cs 的空類別檔案。 Controllers 目錄名稱是慣例。 目錄名稱來自 Web API 使用的 model-view-controller 架構。
注意
依照慣例,控制器類別名稱會後綴為 Controller。
將下列程式代碼新增至 Controllers/PizzaController.cs。 儲存您的變更。
using ContosoPizza.Models; using ContosoPizza.Services; using Microsoft.AspNetCore.Mvc; namespace ContosoPizza.Controllers; [ApiController] [Route("[controller]")] public class PizzaController : ControllerBase { public PizzaController() { } // GET all action // GET by Id action // POST action // PUT action // DELETE action }如您先前所了解的,這個類別衍生自
ControllerBase,也就是在 ASP.NET Core 中使用 HTTP 要求的基底類別。 其也包含您所了解到的兩個標準屬性:[ApiController]和[Route]。 如同先前一樣,[Route]屬性會定義[controller]權杖的對應。 由於此控制器類別已命名為PizzaController,因此對https://localhost:{PORT}/pizza的要求會由此控制器處理。
取得所有披薩
您需要實作的第一個 REST 指令動詞是 GET,在其中用戶端可以從 API 取得所有披薩。 您可以使用內建 [HttpGet] 屬性來定義從我們的服務傳回披薩的方法。
請將 // GET all action 中的 註解替換為以下程式碼:
[HttpGet]
public ActionResult<List<Pizza>> GetAll() =>
PizzaService.GetAll();
上述動作:
- 只回應
GET屬性表示的 HTTP[HttpGet]動詞。 - 傳回
ActionResult類型的List<Pizza>執行個體。ActionResult類型是 ASP.NET Core 中所有動作結果的基底類別。 - 查詢所有披薩的服務,並自動傳回資料,其中具有
Content-Type的application/json值。
取出單一披薩
用戶端可能也會想要要求特定披薩的相關資訊,而不是整個清單。 您可以實作需要 GET 參數的另一個 id 動作。 您可以使用內建 [HttpGet("{id}")] 屬性來定義從我們的服務傳回披薩的方法。 路由邏輯會註冊 [HttpGet] (沒有 id) 和 [HttpGet("{id}")] (有 id) 來作為兩個不同的路由。 接著可以撰寫個別的動作來取出單一項目。
請將 // GET by Id action 中的 註解替換為以下程式碼:
[HttpGet("{id}")]
public ActionResult<Pizza> Get(int id)
{
var pizza = PizzaService.Get(id);
if(pizza == null)
return NotFound();
return pizza;
}
上述動作:
- 只回應
GET屬性表示的 HTTP[HttpGet]動詞。 - 需要將
id參數的值加入 URL 的pizza/後方。 請記住,控制器層級的[Route]屬性會定義/pizza模式。 - 查詢資料庫找出符合所提供
id參數的披薩。
每個用於上述動作的 ActionResult 執行個體,都會對應至下表中的相應 HTTP 狀態碼:
| ASP.NET Core 動作結果 |
HTTP 狀態碼 | 描述 |
|---|---|---|
意指 Ok |
200 | 符合所提供 id 參數的產品存在於記憶體內部快取中。產品包含在媒體類型的回應本文中,而此回應本文定義在 accept HTTP 要求標題 (預設為 JSON) 中。 |
NotFound |
404 | 符合所提供 id 參數的產品未存在於記憶體內部快取中。 |
建置並執行新的控制器
執行下列命令來建立並啟動 Web API:
dotnet run
使用 HTTP 檔案測試控制器
開啟 ContosoPizza.HTTP
新增一個GET以在
Pizza分隔符下呼叫###端點:GET {{ContosoPizza_HostAddress}}/pizza/ Accept: application/json ###請在這個新 GET 呼叫上方選取 傳送要求 命令。
上述命令會以 JSON 格式傳回所有披薩的清單:
HTTP/1.1 200 OK Connection: close Content-Type: application/json; charset=utf-8 Date: Wed, 17 Jan 2024 16:57:09 GMT Server: Kestrel Transfer-Encoding: chunked [ { "id": 1, "name": "Classic Italian", "isGlutenFree": false }, { "id": 2, "name": "Veggie", "isGlutenFree": true } ]若要查詢單一披薩,您可以提出另一個
GET要求,但是使用下列命令傳入id參數:GET {{ContosoPizza_HostAddress}}/pizza/1 Accept: application/json ###上述命令會傳回具有下列輸出的
Classic Italian:HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 Date: Fri, 02 Apr 2021 21:57:57 GMT Server: Kestrel Transfer-Encoding: chunked { "id": 1, "name": "Classic Italian", "isGlutenFree": false }我們的 API 也會處理項目不存在的情況。 請再次呼叫 API,但是使用下列命令傳入無效的披薩
id參數:GET {{ContosoPizza_HostAddress}}/pizza/5 Accept: application/json ###上述命令會傳回具有下列輸出的
404 Not Found錯誤:HTTP/1.1 404 Not Found Content-Type: application/problem+json; charset=utf-8 Date: Fri, 02 Apr 2021 22:03:06 GMT Server: Kestrel Transfer-Encoding: chunked { "type": "https://tools.ietf.org/html/rfc7231#section-6.5.4", "title": "Not Found", "status": 404, "traceId": "00-ec263e401ec554b6a2f3e216a1d1fac5-4b40b8023d56762c-00" }
現在您已完成實作 GET 動詞。 在下一個單元中,您可以將更多動作新增至 PizzaController 以支援披薩資料的 CRUD 作業。
選擇性:使用命令列 HTTP「讀取、求值、輸出」迴圈 (REPL) 測試控制器
藉由從主功能表中選取 [終端機]
httprepl[新增終端機]>,以從 Visual Studio Code 開啟現有的 終端機或開啟新的整合式終端機。執行下列命令來連線至 Web API:
httprepl https://localhost:{PORT}或者,也可以在
HttpRepl執行期間的任何時候執行下列命令:connect https://localhost:{PORT}若要查看新推出的
Pizza端點,請執行下列命令:ls上述命令會偵測已連線端點上所有可用的 API。 應該會顯示下列程式碼:
https://localhost:{PORT}/> ls . [] Pizza [GET] WeatherForecast [GET]執行下列命令,以前往
Pizza端點:cd Pizza上述命令會顯示
Pizza端點的可用 API 輸出:https://localhost:{PORT}/> cd Pizza /Pizza [GET]使用下列命令,在
GET中提出HttpRepl要求:get上述命令會以 JSON 格式傳回所有披薩的清單:
HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 Date: Fri, 02 Apr 2021 21:55:53 GMT Server: Kestrel Transfer-Encoding: chunked [ { "id": 1, "name": "Classic Italian", "isGlutenFree": false }, { "id": 2, "name": "Veggie", "isGlutenFree": true } ]若要查詢單一披薩,您可以提出另一個
GET要求,但是使用下列命令傳入id參數:get 1上述命令會傳回具有下列輸出的
Classic Italian:HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 Date: Fri, 02 Apr 2021 21:57:57 GMT Server: Kestrel Transfer-Encoding: chunked { "id": 1, "name": "Classic Italian", "isGlutenFree": false }我們的 API 也會處理項目不存在的情況。 請再次呼叫 API,但是使用下列命令傳入無效的披薩
id參數:get 5上述命令會傳回具有下列輸出的
404 Not Found錯誤:HTTP/1.1 404 Not Found Content-Type: application/problem+json; charset=utf-8 Date: Fri, 02 Apr 2021 22:03:06 GMT Server: Kestrel Transfer-Encoding: chunked { "type": "https://tools.ietf.org/html/rfc7231#section-6.5.4", "title": "Not Found", "status": 404, "traceId": "00-ec263e401ec554b6a2f3e216a1d1fac5-4b40b8023d56762c-00" }返回 Visual Studio Code 下拉式清單中的
dotnet終端機,然後選取鍵盤的 CTRL+C 來關閉 Web API。
現在您已完成實作 GET 動詞。 在下一個單元中,您可以將更多動作新增至 PizzaController 以支援披薩資料的 CRUD 作業。