練習 - 新增控制器

已完成

控制器是具有一或多個稱為動作之公用方法的公用類別。 依照慣例,控制器會放在專案根目錄的 Controllers 目錄中。 動作會公開為 Web API 控制器內的 HTTP 端點。

建立控制器

  1. 選取 Visual Studio Code 中的 Controllers 資料夾,然後新增名為 PizzaController.cs 的新檔案。

    顯示將新檔案新增至 Controllers 資料夾的 Visual Studio Code 螢幕快照。

    Controllers 目錄中會建立名為 PizzaController.cs 的空類別檔案。 Controllers 目錄名稱是慣例。 目錄名稱來自 Web API 使用的 model-view-controller 架構。

    注意

    依照慣例,控制器類別名稱會後綴為 Controller

  2. 將下列程式代碼新增至 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-Typeapplication/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 檔案測試控制器

  1. 開啟 ContosoPizza.HTTP

  2. 新增一個GET以在Pizza分隔符下呼叫###端點:

    GET {{ContosoPizza_HostAddress}}/pizza/
    Accept: application/json
    
    ###
    
  3. 請在這個新 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
        }
    ]   
    
  4. 若要查詢單一披薩,您可以提出另一個 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
    }
    
  5. 我們的 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) 測試控制器

  1. 藉由從主功能表中選取 [終端機]httprepl [新增終端機]>,以從 Visual Studio Code 開啟現有的 終端機或開啟新的整合式終端機。

  2. 執行下列命令來連線至 Web API:

    httprepl https://localhost:{PORT}
    

    或者,也可以在 HttpRepl 執行期間的任何時候執行下列命令:

    connect https://localhost:{PORT}
    
  3. 若要查看新推出的 Pizza 端點,請執行下列命令:

    ls
    

    上述命令會偵測已連線端點上所有可用的 API。 應該會顯示下列程式碼:

     https://localhost:{PORT}/> ls
     .                 []
     Pizza             [GET]
     WeatherForecast   [GET]
    
  4. 執行下列命令,以前往 Pizza 端點:

    cd Pizza
    

    上述命令會顯示 Pizza 端點的可用 API 輸出:

    https://localhost:{PORT}/> cd Pizza
    /Pizza    [GET]
    
  5. 使用下列命令,在 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
          }
      ]
    
  6. 若要查詢單一披薩,您可以提出另一個 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
    }
    
  7. 我們的 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"
    }
    
  8. 返回 Visual Studio Code 下拉式清單中的 dotnet 終端機,然後選取鍵盤的 CTRL+C 來關閉 Web API。

現在您已完成實作 GET 動詞。 在下一個單元中,您可以將更多動作新增至 PizzaController 以支援披薩資料的 CRUD 作業。