添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
跑龙套的手链  ·  7 ...·  1 月前    · 
纯真的脸盆  ·  National Bureau of ...·  1 年前    · 

蒂姆·德施里弗 里克·安德森

本教學課程將教導建置使用資料庫之控制器型 Web API 的基本概念。 在 ASP.NET Core 中建立 API 的另一種方法是建立最小的 API 。 如需在最小 API 與控制器型 API 之間進行選擇的協助,請參閱 API 概觀 。 如需建立最小 API 的教學課程,請參閱 教學課程:使用 ASP.NET Core 建立最小 API

Overview

本教學課程會建立以下 API:

Description Request body Response body .NET 9 SDK(軟體開發工具包)

您可以遵循 macOS、Linux 或 Windows 上的 Visual Studio Code 指示。 如果您使用 Visual Studio Code 以外的整合式開發環境 (IDE),則可能需要進行變更。

建立 Web API 專案

  • 在搜尋方塊中輸入 Web API
  • 選取 [ASP.NET Core Web API 範本],然後選取 [ 下一步 ]。
  • 在 [ 設定新專案] 對話框中 ,將專案命名為 TodoApi ,然後選取 [ 下一步 ]。
  • 在 [其他資訊] 對話方塊中:
    • 確認 框架 .NET 9.0(標準期限支援)。
    • 確認已核取 [啟用 OpenAPI 支援 ] 複選框。
    • 確認 使用控制器的複選框已勾選(取消勾選以使用簡化 API)。
    • Select Create .
    • 新增 NuGet 套件

      必須新增 NuGet 套件,才能支援本教學課程中使用的資料庫。

    • 在 [工具] 功能表上,選取 [NuGet 套件管理員] > [管理解決方案的 NuGet 套件]
    • 選取 瀏覽 索引標籤。
    • 在搜尋方塊中輸入 Microsoft.EntityFrameworkCore.InMemory ,然後選取 Microsoft.EntityFrameworkCore.InMemory
    • 選取右窗格中的 [專案] 核取方塊,然後選取 [安裝]
    • dotnet new webapi --use-controllers -o TodoApi
      cd TodoApi
      dotnet add package Microsoft.EntityFrameworkCore.InMemory
      code -r ../TodoApi
      

      These commands:

    • 建立新的 Web API 專案,然後在 Visual Studio Code 中予以開啟。
    • 新增下一節所需的 NuGet 套件。
    • 在 Visual Studio Code 的目前實例中開啟 TodoApi 資料夾。
    • Visual Studio Code 可能會顯示一個對話框,詢問: 您信任此資料夾中檔案的作者嗎?

    • 如果您信任父資料夾中的所有檔案,請選取 [信任父資料夾中所有檔案的作者]
    • 選取 [是,信任作者],因為專案資料夾有 .NET 產生的檔案。
    • 當 Visual Studio Code 要求您新增資產以建置和偵錯專案時,請選取 [是]。 如果 Visual Studio Code 不提供新增建置和偵錯資產,請選取 [檢視]>[命令選擇區],然後在搜尋方塊中輸入「.NET」。 從命令清單中選取 .NET: Generate Assets for Build and Debug 命令。
    • Visual Studio Code 會新增 .vscode 資料夾,其中包含產生的 launch.jsontasks.json 檔案。

      若您同意信任開發憑證,請選取 [是]

      如需信任 Firefox 瀏覽器的資訊,請參閱 Firefox SEC_ERROR_INADEQUATE_KEY_USAGE憑證錯誤

      Visual Studio 會啟動終端機視窗,並顯示執行中應用程式的 URL。 API 裝載於 https://localhost:<port>,其中 <port> 是專案建立時設定的隨機選擇埠號碼。

      info: Microsoft.Hosting.Lifetime[14] Now listening on: https://localhost:7260 info: Microsoft.Hosting.Lifetime[14] Now listening on: http://localhost:7261 info: Microsoft.Hosting.Lifetime[0] Application started. Press Ctrl+C to shut down. Ctrl+按一下輸出中的 HTTPS URL,以在瀏覽器中測試 Web 應用程式。 在 https://localhost:<port>,沒有端點,因此瀏覽器會回傳 HTTP 404 找不到

      /weatherforecast 附加至 URL 以測試 WeatherForecast API。 瀏覽器會顯示類似下列範例的 JSON:

      "date": "2025-07-16", "temperatureC": 52, "temperatureF": 125, "summary": "Mild" "date": "2025-07-17", "temperatureC": 36, "temperatureF": 96, "summary": "Warm" "date": "2025-07-18", "temperatureC": 39, "temperatureF": 102, "summary": "Cool" "date": "2025-07-19", "temperatureC": 10, "temperatureF": 49, "summary": "Bracing" "date": "2025-07-20", "temperatureC": -1, "temperatureF": 31, "summary": "Chilly"

      上述命令需要Linux上的.NET 9或更新版本 SDK。 針對 .NET 8.0.401 或更早版本的 SDK 上的 Linux,請參閱 Linux 發行版的文件以建立憑證信任。

      若憑證先前不受信任,則上述命令會顯示下列對話方塊:

      Ctrl+按一下輸出中的 HTTPS URL,以在瀏覽器中測試 Web 應用程式。

    • 預設瀏覽器會啟動至 https://localhost:<port>,其中 <port> 是輸出中顯示的隨機選擇連接埠號碼。 在 https://localhost:<port>,沒有端點,因此瀏覽器會回傳 HTTP 404 找不到

    • /weatherforecast 附加至 URL 以測試 WeatherForecast API。 瀏覽器會顯示類似下列範例的 JSON:

      "date": "2025-07-16", "temperatureC": 52, "temperatureF": 125, "summary": "Mild" "date": "2025-07-17", "temperatureC": 36, "temperatureF": 96, "summary": "Warm" "date": "2025-07-18", "temperatureC": 39, "temperatureF": 102, "summary": "Cool" "date": "2025-07-19", "temperatureC": 10, "temperatureF": 49, "summary": "Bracing" "date": "2025-07-20", "temperatureC": -1, "temperatureF": 31, "summary": "Chilly"
    • 使用下列指示測試 Web 應用程式之後,請在整合式終端機中按 ctrl+C,以關閉它。
    • 使用 Swagger 建立 API 測試 UI

      有許多可用的 Web API 測試工具可供選擇,您可以使用您慣用的工具遵循本教學課程的簡介 API 測試步驟。

      本教學課程會使用 .NET 套件 NSwag.AspNetCore,其整合了 Swagger 工具以產生符合 OpenAPI 規格的測試 UI:

    • NSwag:.NET 連結庫,可將 Swagger 直接整合到 ASP.NET Core 應用程式,並提供中介軟體和設定。
    • Swagger:一組開放原始碼工具,例如 OpenAPIGenerator 和 SwaggerUI,可產生遵循 OpenAPI 規格的 API 測試頁面。
    • OpenAPI 規格:根據控制器和模型內的 XML 和屬性註釋來描述 API 功能的文件。
    • 如需搭配 ASP.NET 使用 OpenAPI 和 NSwag 的詳細資訊,請參閱 使用 Swagger / OpenAPI 的 ASP.NET Core Web API 文件

      安裝 Swagger 工具

    • 執行以下命令:

      dotnet add package NSwag.AspNetCore
      

      上面的命令會新增 NSwag.AspNetCore 套件,其中包含用來產生 Swagger 文件和 UI 的工具。 因為我們的專案是使用 OpenAPI,所以我們只會使用 NSwag 套件來產生 Swagger UI。

      設定 Swagger 中介軟體

    • Program.cs中,加入下列醒目標示的程式碼:
    • var app = builder.Build();
      if (app.Environment.IsDevelopment())
          app.MapOpenApi();
          app.UseSwaggerUi(options =>
              options.DocumentPath = "/openapi/v1.json";
      

      先前的程式代碼會啟用 Swagger 中間件,以使用 Swagger UI 提供產生的 JSON 檔。 Swagger 只會在開發環境中啟用。 在生產環境中啟用 Swagger 可能會公開關於 API 結構和實作的潛在敏感性詳細資料。

      應用程式會使用 OpenApi 所產生的 OpenAPI 檔,位於 /openapi/v1.json,來產生 UI。 在專案運行時,透過瀏覽器前往 WeatherForecast,以檢視 https://localhost:<port>/openapi/v1.json API 所生成的 OpenAPI 規格。

      OpenAPI 規格是 JSON 格式的檔,可描述 API 的結構和功能,包括端點、要求/回應格式、參數等等。 它基本上是 API 的藍圖,可供各種工具用來瞭解並與您的 API 互動。

      新增模型類別

      「模型」是代表應用程式所管理資料的一組類別。 此應用程式的模型是 TodoItem 類別。

    • [方案總管] 中,用滑鼠右鍵點擊專案。 選擇 新增>新資料夾。 將資料夾命名為 Models
    • 以滑鼠右鍵按一下 Models 資料夾並選取 [新增]>[類別]。 將類別命名為 TodoItem ,然後選取 [ 新增]。
    • 以下列項目取代範本程式碼:
    • namespace TodoApi.Models;
      public class TodoItem
          public long Id { get; set; }
          public string? Name { get; set; }
          public bool IsComplete { get; set; }
          public long Id { get; set; }
          public string? Name { get; set; }
          public bool IsComplete { get; set; }
      public class TodoContext : DbContext
          public TodoContext(DbContextOptions<TodoContext> options)
              : base(options)
          public DbSet<TodoItem> TodoItems { get; set; } = null!;
      public class TodoContext : DbContext
          public TodoContext(DbContextOptions<TodoContext> options)
              : base(options)
          public DbSet<TodoItem> TodoItems { get; set; } = null!;
      

      登錄資料庫內容

      在 ASP.NET Core 中,DB 內容之類的服務必須向 相依性插入 (DI) 容器註冊。 此容器會將服務提供給控制器。

      使用下列醒目的程式碼更新 Program.cs

      using Microsoft.EntityFrameworkCore;
      using TodoApi.Models;
      var builder = WebApplication.CreateBuilder(args);
      builder.Services.AddControllers();
      builder.Services.AddOpenApi();
      builder.Services.AddDbContext<TodoContext>(opt =>
          opt.UseInMemoryDatabase("TodoList"));
      var app = builder.Build();
      if (app.Environment.IsDevelopment())
          app.MapOpenApi();
      app.UseHttpsRedirection();
      app.UseAuthorization();
      app.MapControllers();
      app.Run();
      

      上述 程式碼:

    • 加入 using 指令。
    • 將資料庫內容新增至 DI 容器。
    • 指定資料庫內容將會使用記憶體內部資料庫。
    • 生成控制器

    • 選取 [使用 Entity Framework 執行動作的 API 控制器],然後選取 [新增]

    • 在 [新增具有動作且使用 Entity Framework 的 API 控制器] 對話方塊中:

    • 在 [模型類別] 中選取 [TodoItem (TodoApi.Models)]
    • 資料內容類別中選取 TodoContext (TodoApi.Models)
    • Select Add.
    • 如果搭建操作失敗,請選取 [新增] 以嘗試再次進行搭建。

      此步驟會將 Microsoft.VisualStudio.Web.CodeGeneration.DesignMicrosoft.EntityFrameworkCore.Tools NuGet 套件新增至專案。 這些套件是 Scaffolding 所需的。

      請確定到目前為止的所有變更都已儲存。

    • 以滑鼠右鍵按兩下 [macOS] TodoAPI 項目,然後選取 [ 在終端機中開啟]。 終端機會在 TodoAPI 專案資料夾開啟。 執行下列命令:
    • dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design
      dotnet add package Microsoft.EntityFrameworkCore.Design
      dotnet add package Microsoft.EntityFrameworkCore.SqlServer
      dotnet add package Microsoft.EntityFrameworkCore.Tools
      dotnet tool uninstall -g dotnet-aspnet-codegenerator
      dotnet tool install -g dotnet-aspnet-codegenerator
      dotnet tool update -g dotnet-aspnet-codegenerator
      

      上述命令:

    • 新增腳手架 (Scaffolding) 所需的 NuGet 套件。
    • 在解除安裝任何可能的舊版本後,再安裝腳手架引擎 (dotnet-aspnet-codegenerator)。
    • 針對 Linux,使用下列命令將 .NET 工具目錄新增至系統路徑:

      echo 'export PATH=$HOME/.dotnet/tools:$PATH' >> ~/.bashrc
      source ~/.bashrc
      

      根據預設,要安裝的 .NET 二進位檔架構代表目前執行的 OS 架構。 若要指定不同的OS架構,請參閱 dotnet tool install, --arch 選項。 如需詳細資訊,請參閱 GitHub 問題 dotnet/AspNetCore.Docs #29262

      組建專案。

      執行以下命令:

      dotnet aspnet-codegenerator controller -name TodoItemsController -async -api -m TodoItem -dc TodoContext -outDir Controllers
      

      上述命令會生成 TodoItemsController 的框架。

      產生的程式碼:

    • 使用 [ApiController] 屬性標記類別。 這個屬性表示控制器會回應 Web API 要求。 如需屬性啟用的特定行為相關信息,請參閱 使用 ASP.NET Core 建立 Web API
    • 使用 DI 將資料庫內容 (TodoContext) 插入到控制器中。 控制器中的每一個 CRUD 方法都會使用資料庫內容。
    • ASP.NET Core 範本適用於:

    • 路由範本中檢視包含 [action] 的控制器。
    • API 控制器在路由範本中不包含 [action]
    • [action] 權杖不在路由範本中時,動作名稱 (方法名稱) 不會包含在端點中。 也就是說,動作的關聯方法名稱並未用於路由匹配。

      更新 PostTodoItem 建立方法

      更新 PostTodoItem 中的 return 陳述式,以使用 nameof 運算子:

      [HttpPost]
      public async Task<ActionResult<TodoItem>> PostTodoItem(TodoItem todoItem)
          _context.TodoItems.Add(todoItem);
          await _context.SaveChangesAsync();
          //    return CreatedAtAction("GetTodoItem", new { id = todoItem.Id }, todoItem);
          return CreatedAtAction(nameof(GetTodoItem), new { id = todoItem.Id }, todoItem);
      

      上述程式碼是 HTTP POST 方法,以 [HttpPost] 屬性表示。 該方法會從 HTTP 要求本文取得 TodoItem 的值。

      如需詳細資訊,請參閱 使用 Http[Verb] 屬性的屬性路由

      CreatedAtAction 方法:

    • 如果成功,會傳回 HTTP 201 狀態代碼 。 對於可在伺服器上建立新資源的 HTTP 201 方法,HTTP POST 是標準回應。
    • Location標頭新增到回應。 Location 標頭會指定新建待辦事項的 URI。 如需詳細資訊,請參閱 10.2.2 201 已建立
    • 參考 GetTodoItem 動作以建立 Location 標頭的 URI。 C# nameof 關鍵字是用來避免在 CreatedAtAction 呼叫中以硬式編碼方式寫入動作名稱。
    • Test PostTodoItem

      隨即會在專案資料夾中建立名為 TodoApi.http 的新檔案,其內容類別似下列範例:

      @TodoApi_HostAddress = https://localhost:49738
      POST {{TodoApi_HostAddress}}/api/todoitems
      Content-Type: application/json
        //TodoItem
      
    • 第一行會建立用於所有端點的變數。
    • 下一行會定義 POST 要求。
    • POST 要求行之後的行會定義標頭,以及為要求本文提供一個佔位符。
    • 三重主題標籤 (###) 行是要求分隔符號:其之後則用於不同的要求。
    • POST 請求需要 TodoItem。 若要定義 todo,請使用下列 JSON 取代 //TodoItem 批註:

      "name": "walk dog", "isComplete": true

      TodoApi.http 檔案現在看起來應該類似下列範例,但有您的連接埠號碼:

      @TodoApi_HostAddress = https://localhost:7260
      Post {{TodoApi_HostAddress}}/api/todoitems
      Content-Type: application/json
        "name": "walk dog",
        "isComplete": true
      
    • 執行應用程式。

    • 選取 要求行上方的 [傳送要求]POST 連結。

      請記下一些實用的詳細資料:

    • cURL:Swagger 提供 Unix/Linux 語法的範例 cURL 命令,可以在任何使用 Unix/Linux 語法的 bash 殼層中的指令列執行,包括 Git for Windows 的 Git Bash。
    • 要求 URL:Swagger UI 的 JavaScript 程式碼針對 API 呼叫所發出 HTTP 要求的簡化表示法。 實際請求可能包含標頭、查詢參數以及請求主體等詳細資料。
    • 伺服器回應:包含回應本文和標頭資訊。 回應本文顯示 id 已設定為 1
    • 回應碼:傳回 201 HTTP 狀態碼,指出已成功處理要求,並導致建立新的資源。
    • 測試位置標頭中的 URI

      從瀏覽器呼叫GET端點或使用Endpoints Explorer,以測試應用程式。 下列步驟適用於 端點總管

    • 在 [端點總管] 中,以滑鼠右鍵按一下第一個 GET 端點,然後選取 [產生要求]

      下列內容會新增至 TodoApi.http 檔案:

      GET {{TodoApi_HostAddress}}/api/todoitems
      
    • 選取新 要求行上方的 [傳送要求]GET 連結。

      GET 要求會傳送至應用程式,而回應會顯示在 [回應] 窗格中。

    • 回應主體類似以下 JSON:

      "id": 1, "name": "walk dog", "isComplete": true
    • 在 [端點總管] 中,以滑鼠右鍵按一下 /api/todoitems/{id}GET 端點,然後選取 [產生要求]。 下列內容會新增至 TodoApi.http 檔案:

      @id=0
      GET {{TodoApi_HostAddress}}/api/todoitems/{{id}}
      
    • {@id} 指派給 1(而不是 0)。

    • 選取新 GET 要求行上方的 [傳送要求] 連結。

      GET 要求會傳送至應用程式,而回應會顯示在 [回應] 窗格中。

    • 回應主體類似以下 JSON:

      "id": 1, "name": "walk dog", "isComplete": true
    • 在 Swagger 中,選取 [GET /api/todoitems>試用>執行]。

    • 或者,輸入 URI ,從瀏覽器呼叫 https://localhost:<port>/api/todoitems。 例如, https://localhost:7260/api/todoitems

      GET /api/todoitems 的呼叫會產生類似下列的回應:

      "id": 1, "name": "walk dog", "isComplete": true
    • 在 Swagger 中呼叫 GET /api/todoitems/{id} 以從特定 ID 返回資料。

    • 選取 GET /api/todoitems>試試看
    • 將 [識別碼] 欄位設定為 1,然後選取 [執行]
    • 或者,輸入 URI ,從瀏覽器呼叫 https://localhost:<port>/api/todoitems/1。 例如, https://localhost:7260/api/todoitems/1

    • 回應類似以下:

      "id": 1, "name": "walk dog", "isComplete": true

      上一節顯示 /api/todoitems/{id} 路由的範例。

      依照 POST 指示新增另一個待辦事項,然後使用 Swagger 測試 /api/todoitems 路由。

      這個應用程式會使用記憶體內部資料庫。 如果應用程式在停止後再啟動,上述 GET 要求不會傳回任何資料。 如果未傳回任何數據,請將 POST 資料傳送至應用程式。

      路由和 URL 路徑

      [HttpGet] 屬性代表回應 HTTP GET 要求的方法。 每個方法的 URL 路徑的建構方式如下:

    • 一開始在控制器的 Route 屬性中使用範本字串:

      [Route("api/[controller]")]
      [ApiController]
      public class TodoItemsController : ControllerBase
      
    • 以控制器的名稱取代 [controller],也就是將控制器類別名稱減去 "Controller" 字尾。 在此範例中,控制器類別名稱是 TodoItemsController,因此控制器名稱是 "TodoItems"。 ASP.NET 核心 路由 不區分大小寫。

    • 如果 [HttpGet] 屬性具有路由範本 (例如 [HttpGet("products")]),請將其附加到路徑。 此範例不使用範本。 如需詳細資訊,請參閱 使用 Http[Verb] 屬性的屬性路由

      在下列 GetTodoItem 方法中,"{id}" 是待辦事項唯一識別碼的預留位置變數。 在叫用 GetTodoItem 時,會將 URL 中的 "{id}" 值提供給方法的 id 參數。

      [HttpGet("{id}")]
      public async Task<ActionResult<TodoItem>> GetTodoItem(long id)
          var todoItem = await _context.TodoItems.FindAsync(id);
          if (todoItem == null)
              return NotFound();
          return todoItem;
      

      Return values

      GetTodoItemsGetTodoItem 方法的傳回類型為 ActionResult<T> 類型。 ASP.NET Core 會自動將物件序列化為 JSON,並將 JSON 寫入至回應訊息的本文。 此傳回類型的回應碼為 200 OK,假設沒有未處理的例外狀況。 未處理的例外狀況會轉譯成 5xx 錯誤。

      ActionResult 傳回型別可代表各種 HTTP 狀態碼。 例如,GetTodoItem 可傳回兩個不同的狀態值:

    • 如果沒有項目符合所要求的識別碼,方法會傳回 404 狀態NotFound 錯誤碼。
    • 否則,該方法會傳回 200 並包含 JSON 回應主體。 傳回 item 結果將得到 HTTP 200 回應。
    • PutTodoItem 方法

      檢查 PutTodoItem 方法:

      [HttpPut("{id}")]
      public async Task<IActionResult> PutTodoItem(long id, TodoItem todoItem)
          if (id != todoItem.Id)
              return BadRequest();
          _context.Entry(todoItem).State = EntityState.Modified;
              await _context.SaveChangesAsync();
          catch (DbUpdateConcurrencyException)
              if (!TodoItemExists(id))
                  return NotFound();
                  throw;
          return NoContent();
                    PutTodoItem 類似於 PostTodoItem,但是會使用 HTTP PUT。 回應為 204(無內容)。 根據 HTTP 規格,PUT 要求用戶端傳送完整更新的實體,而不只是變更。 若要支援部分更新,請使用 HTTP PATCH

      測試 PutTodoItem 方法

      每次啟動應用程式時,此範例使用的記憶體內部資料庫必須被初始化。 資料庫中必須有項目,您才能進行 PUT 呼叫。 在發出 PUT 呼叫之前,呼叫 GET 以確保資料庫中有項目。

      使用 PUT 方法來更新識別碼 = 1 的 TodoItem,並將其名稱設定為 "feed fish"。 請注意,回應為 HTTP 204 No Content

    • 在 [端點總管] 中,以滑鼠右鍵按一下 PUT 端點,然後選取 [產生要求]

      下列內容會新增至 TodoApi.http 檔案:

      PUT {{TodoApi_HostAddress}}/api/todoitems/{{id}}
      Content-Type: application/json
        //TodoItem
      
    • 在 PUT 要求行中,將 {{id}} 取代為 1

    • 使用以下內容取代 //TodoItem 佔位符:

      PUT {{TodoApi_HostAddress}}/api/todoitems/1
      Content-Type: application/json
        "id": 1,
        "name": "feed fish",
        "isComplete": false
      
    • 選取新 PUT 要求行上方的 [傳送要求] 連結。

      PUT 要求會傳送至應用程式,而回應會顯示在 [回應] 窗格中。 回應本文是空白,而狀態碼為 204。

      檢查 DeleteTodoItem 方法:

      [HttpDelete("{id}")]
      public async Task<IActionResult> DeleteTodoItem(long id)
          var todoItem = await _context.TodoItems.FindAsync(id);
          if (todoItem == null)
              return NotFound();
          _context.TodoItems.Remove(todoItem);
          await _context.SaveChangesAsync();
          return NoContent();
      

      測試 DeleteTodoItem 方法

      使用 DELETE 方法來刪除識別碼 = 1 的 TodoItem。 請注意,回應為 HTTP 204 No Content

    • 將 DELETE 要求行中的 {{id}} 取代為 1。 DELETE 要求看起來應該類似下列範例:

      DELETE {{TodoApi_HostAddress}}/api/todoitems/{{id}}
      
    • 傳送請求 連結以進行 DELETE 請求。

      DELETE 要求會傳送至應用程式,而回應會顯示在 [回應] 窗格中。 回應本文是空白,而狀態碼為 204。

      Prevent over-posting

      目前範例應用程式會公開整個 TodoItem 物件。 生產應用程式通常會限制輸入的資料,並使用模型的子集傳回。 背後有多個原因,而安全性是主要原因。 模型的子集通常稱為資料傳輸物件 (DTO)、輸入模型或檢視模型。 本教學課程中使用 DTO

      DTO 可以用來:

    • Prevent over-posting.
    • 隱藏用戶端不應該檢視的屬性。
    • 省略一些屬性,以減少承載大小。
    • 將包含巢狀物件的物件圖扁平化。 扁平化的物件圖譜可能對客戶端來說更加方便。
    • 若要示範 DTO 方法,請更新 TodoItem 類別以包含祕密欄位:

      namespace TodoApi.Models;
      public class TodoItem
          public long Id { get; set; }
          public string? Name { get; set; }
          public bool IsComplete { get; set; }
          public string? Secret { get; set; }
      

      必須將祕密欄位從此應用程式中隱藏,但管理應用程式可以選擇顯示它。

      驗證您可以提交並取得隱私欄位。

      Models/TodoItemsDTO.cs 檔案中建立 DTO 模型:

      namespace TodoApi.Models;
      public class TodoItemDTO
          public long Id { get; set; }
          public string? Name { get; set; }
          public bool IsComplete { get; set; }
      

      更新 TodoItemsController 以使用 TodoItemDTO

      using Microsoft.AspNetCore.Mvc;
      using Microsoft.EntityFrameworkCore;
      using TodoApi.Models;
      namespace TodoApi.Controllers;
      [Route("api/[controller]")]
      [ApiController]
      public class TodoItemsController : ControllerBase
          private readonly TodoContext _context;
          public TodoItemsController(TodoContext context)
              _context = context;
          // GET: api/TodoItems
          [HttpGet]
          public async Task<ActionResult<IEnumerable<TodoItemDTO>>> GetTodoItems()
              return await _context.TodoItems
                  .Select(x => ItemToDTO(x))
                  .ToListAsync();
          // GET: api/TodoItems/5
          // <snippet_GetByID>
          [HttpGet("{id}")]
          public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
              var todoItem = await _context.TodoItems.FindAsync(id);
              if (todoItem == null)
                  return NotFound();
              return ItemToDTO(todoItem);
          // </snippet_GetByID>
          // PUT: api/TodoItems/5
          // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
          // <snippet_Update>
          [HttpPut("{id}")]
          public async Task<IActionResult> PutTodoItem(long id, TodoItemDTO todoDTO)
              if (id != todoDTO.Id)
                  return BadRequest();
              var todoItem = await _context.TodoItems.FindAsync(id);
              if (todoItem == null)
                  return NotFound();
              todoItem.Name = todoDTO.Name;
              todoItem.IsComplete = todoDTO.IsComplete;
                  await _context.SaveChangesAsync();
              catch (DbUpdateConcurrencyException) when (!TodoItemExists(id))
                  return NotFound();
              return NoContent();
          // </snippet_Update>
          // POST: api/TodoItems
          // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
          // <snippet_Create>
          [HttpPost]
          public async Task<ActionResult<TodoItemDTO>> PostTodoItem(TodoItemDTO todoDTO)
              var todoItem = new TodoItem
                  IsComplete = todoDTO.IsComplete,
                  Name = todoDTO.Name
              _context.TodoItems.Add(todoItem);
              await _context.SaveChangesAsync();
              return CreatedAtAction(
                  nameof(GetTodoItem),
                  new { id = todoItem.Id },
                  ItemToDTO(todoItem));
          // </snippet_Create>
          // DELETE: api/TodoItems/5
          [HttpDelete("{id}")]
          public async Task<IActionResult> DeleteTodoItem(long id)
              var todoItem = await _context.TodoItems.FindAsync(id);
              if (todoItem == null)
                  return NotFound();
              _context.TodoItems.Remove(todoItem);
              await _context.SaveChangesAsync();
              return NoContent();
          private bool TodoItemExists(long id)
              return _context.TodoItems.Any(e => e.Id == id);
          private static TodoItemDTO ItemToDTO(TodoItem todoItem) =>
             new TodoItemDTO
                 Id = todoItem.Id,
                 Name = todoItem.Name,
                 IsComplete = todoItem.IsComplete
      

      確認您無法張貼或取得祕密欄位。

      使用 JavaScript 呼叫 Web API

      請參閱 教學課程:使用 JavaScript 呼叫 ASP.NET Core Web API

      Web API 影片系列

      請參閱 影片:初學者系列 — 網頁 API

      企業 Web 應用程式模式

      如需建立可靠、安全、高效能、可測試且可調整 ASP.NET 核心應用程式的指引,請參閱 企業 Web 應用程式模式。 提供可實作模式的完整生產品質範例 Web 應用程式。

      將驗證支援新增至 Web API

      ASP.NET Core Identity 會將使用者介面 (UI) 登入功能新增至 ASP.NET Core Web 應用程式。 若要保護 Web API 和 SPA,請使用下列其中一項:

      Microsoft Entra 身份識別
    • Azure Active Directory B2C (Azure AD B2C)
    • Duende Identity 伺服器
    • Duende Identity 伺服器是適用於 ASP.NET Core 的 OpenID Connect 和 OAuth 2.0 架構。 Duende Identity 伺服器會啟用下列安全性功能:

    • 驗證即服務 (AaaS)
    • 多個應用程式類型的單一登入/登出 (SSO)
    • API 的存取控制
    • Federation Gateway
    • Important

      Duende Software 可能會要求您支付授權費用才能在生產環境中使用 Duende Identity 伺服器。 如需詳細資訊,請參閱 從 .NET 5 中的 ASP.NET Core 移轉至 .NET 6

      如需詳細資訊,請參閱 Duende 伺服器檔(Duende Identity Software 網站)。

      發佈至 Azure

      如需部署至 Azure 的資訊,請參閱 快速入門:部署 ASP.NET Web 應用程式

      Additional resources

      檢視或下載本教學課程的範例程序代碼。 請參閱 如何下載

      如需詳細資訊,請參閱以下資源:

      使用 ASP.NET Core 建立 Web API
    • 教學課程:使用 ASP.NET Core 建立最小 API
    • 使用產生的 OpenAPI 檔
    • ASP.NET Core Web API 文件,使用 Swagger / OpenAPI
    • Razor 在 ASP.NET Core 中控制器動作的路由配置
    • ASP.NET Core Web API 中的控制器動作傳回類型
    • 將 ASP.NET Core 應用程式部署至 Azure App Service
    • 裝載和部署 ASP.NET Core 使用 ASP.NET Core 建立 Web API

      本教學課程將教導建置使用資料庫之控制器型 Web API 的基本概念。 在 ASP.NET Core 中建立 API 的另一種方法是建立最小的 API。 如需在最小 API 與控制器型 API 之間進行選擇的協助,請參閱 API 概觀。 如需建立最小 API 的教學課程,請參閱 教學課程:使用 ASP.NET Core 建立最小 API

      Overview

      本教學課程會建立以下 API:

      Description Request body Response body

      Important

      Microsoft 已宣佈淘汰 Visual Studio for Mac。 從 2024 年 8 月 31 日起,將不再支援 Visual Studio for Mac。 Alternatives include:

    • Visual Studio Code 搭配 C# 開發工具包 和相關延伸模組,例如 .NET MAUIUnity
    • 在 Mac 的 VM 上執行 Windows 的 Visual Studio IDE。
    • 雲端 VM 中的 Windows 上執行的 Visual Studio IDE。
    • 如需詳細資訊,請參閱 Visual Studio for Mac 淘汰公告

    • 在搜尋方塊中輸入 Web API
    • 選取 [ASP.NET Core Web API 範本],然後選取 [ 下一步]。
    • 在 [ 設定新專案] 對話框中,將專案命名為 TodoApi ,然後選取 [ 下一步]。
    • 在 [其他資訊] 對話方塊中:
      • 確認 Framework.NET 8.0 (長期支援)
      • 確認已勾選 [使用控制器] 複選框(若取消勾選,將使用最少 API)
      • 確認已核取 [啟用 OpenAPI 支援 ] 複選框。
      • Select Create.
      • 新增 NuGet 套件

        必須新增 NuGet 套件,才能支援本教學課程中使用的資料庫。

      • 在 [工具] 功能表上,選取 [NuGet 套件管理員] > [管理解決方案的 NuGet 套件]
      • 選取瀏覽 索引標籤。
      • 在搜尋方塊中輸入 Microsoft.EntityFrameworkCore.InMemory,然後選取 Microsoft.EntityFrameworkCore.InMemory
      • 選取右窗格中的 [專案] 核取方塊,然後選取 [安裝]
      • dotnet new webapi --use-controllers -o TodoApi
        cd TodoApi
        dotnet add package Microsoft.EntityFrameworkCore.InMemory
        code -r ../TodoApi
        

        These commands:

      • 建立新的 Web API 專案,然後在 Visual Studio Code 中予以開啟。
      • 新增下一節所需的 NuGet 套件。
      • 在 Visual Studio Code 的目前實例中開啟 TodoApi 資料夾。
      • Visual Studio Code 可能會顯示一個對話框,詢問: 您信任此資料夾中檔案的作者嗎?

      • 如果您信任父資料夾中的所有檔案,請選取 [信任父資料夾中所有檔案的作者]
      • 選取 [是,信任作者],因為專案資料夾有 .NET 產生的檔案。
      • 當 Visual Studio Code 要求您新增資產以建置和偵錯專案時,請選取 [是]。 如果 Visual Studio Code 不提供新增建置和偵錯資產,請選取 [檢視]>[命令選擇區],然後在搜尋方塊中輸入「.NET」。 從命令清單中選取 .NET: Generate Assets for Build and Debug 命令。
      • Visual Studio Code 會新增 .vscode 資料夾,其中包含產生的 launch.jsontasks.json 檔案。

      • 在 Visual Studio for Mac 2022 工具列中,選取 [專案]>[管理 NuGet 套件...]
      • 在搜尋方塊中,輸入 Microsoft.EntityFrameworkCore.InMemory
      • 在結果視窗中,檢查 Microsoft.EntityFrameworkCore.InMemory
      • 選取 新增套件
      • 在 [選取專案] 視窗中,選取 [確定]
      • 在 [授權合約] 視窗中,選取 [同意]
      • 上述命令需要Linux上的.NET 9或更新版本 SDK。 針對 .NET 8.0.401 或更早版本的 SDK 上的 Linux,請參閱 Linux 發行版的文件以建立憑證信任。

        若憑證先前不受信任,則上述命令會顯示下列對話方塊:

        Ctrl+按一下輸出中的 HTTPS URL,以在瀏覽器中測試 Web 應用程式。

      • 預設瀏覽器會啟動至 https://localhost:<port>/swagger/index.html,其中 <port> 是輸出中顯示的隨機選擇連接埠號碼。 在 https://localhost:<port>,沒有端點,因此瀏覽器會回傳 HTTP 404 找不到。 附加 /swagger 至 URL https://localhost:<port>/swagger

        在下列指示中測試 Web 應用程式之後,請在整合式終端機中按 Ctrl+C 以將其關機。

        選取 [偵錯]>[開始偵錯] 以啟動應用程式。 Visual Studio for Mac 會啟動瀏覽器並瀏覽至 https://localhost:<port>/swagger/index.html,其中 <port> 是專案建立時設定的隨機選擇連接埠號碼。

        Swagger 頁面 /swagger/index.html 隨即顯示。 選取 GET>試試看>執行。 頁面會顯示:

      • 用來測試 WeatherForecast API 的 Curl 命令。
      • 用來測試 WeatherForecast API 的 URL。
      • 回應碼、本文和標頭。
      • 具有媒體類型與範例值和架構的下拉式清單方塊。
      • 如果 Swagger 頁面未出現,請參閱 此 GitHub 問題

        Swagger 可用來為 Web API 產生有用的文件和說明頁面。 本教學課程會使用 Swagger 來測試應用程式。 如需 Swagger 的詳細資訊,請參閱 使用 Swagger / OpenAPI ASP.NET Core Web API 檔

        複製並貼上瀏覽器中的要求 URLhttps://localhost:<port>/weatherforecast

        系統會傳回類似下列範例的 JSON:

        "date": "2019-07-16T19:04:05.7257911-06:00", "temperatureC": 52, "temperatureF": 125, "summary": "Mild" "date": "2019-07-17T19:04:05.7258461-06:00", "temperatureC": 36, "temperatureF": 96, "summary": "Warm" "date": "2019-07-18T19:04:05.7258467-06:00", "temperatureC": 39, "temperatureF": 102, "summary": "Cool" "date": "2019-07-19T19:04:05.7258471-06:00", "temperatureC": 10, "temperatureF": 49, "summary": "Bracing" "date": "2019-07-20T19:04:05.7258474-06:00", "temperatureC": -1, "temperatureF": 31, "summary": "Chilly"

        新增模型類別

        「模型」是代表應用程式所管理資料的一組類別。 此應用程式的模型是 TodoItem 類別。

      • [方案總管] 中,用滑鼠右鍵點擊專案。 選擇 新增>新資料夾。 將資料夾命名為 Models
      • 以滑鼠右鍵按一下 Models 資料夾並選取 [新增]>[類別]。 將類別命名為 TodoItem ,然後選取 [ 新增]。
      • 以下列項目取代範本程式碼:
      • 按住 Ctrl 鍵並按一下 [TodoAPI] 專案,然後選取 [新增]>[新增資料夾]。 將資料夾命名為 Models

      • 按住 Ctrl 鍵並按一下 Models 資料夾,然後選取 [新增]>[新增類別...]>[一般]>[空類別]

      • 將類別命名為 TodoItem,然後選取 [ 建立]。

      • 以下列項目取代範本程式碼:

        public long Id { get; set; } public string? Name { get; set; } public bool IsComplete { get; set; } Id 屬性的功能相當於關聯式資料庫中的唯一索引鍵。

        模型類別可位於專案中的任何位置,但依照慣例會使用 Models 資料夾。

        新增資料庫上下文

        「資料庫內容」是為資料模型協調 Entity Framework 功能的主要類別。 此類別是透過衍生自 Microsoft.EntityFrameworkCore.DbContext 類別來建立。

        public class TodoContext : DbContext public TodoContext(DbContextOptions<TodoContext> options) : base(options) public DbSet<TodoItem> TodoItems { get; set; } = null!;

        登錄資料庫內容

        在 ASP.NET Core 中,DB 內容之類的服務必須向 相依性插入 (DI) 容器註冊。 此容器會將服務提供給控制器。

        使用下列醒目的程式碼更新 Program.cs

        using Microsoft.EntityFrameworkCore;
        using TodoApi.Models;
        var builder = WebApplication.CreateBuilder(args);
        builder.Services.AddControllers();
        builder.Services.AddDbContext<TodoContext>(opt =>
            opt.UseInMemoryDatabase("TodoList"));
        builder.Services.AddEndpointsApiExplorer();
        builder.Services.AddSwaggerGen();
        var app = builder.Build();
        if (app.Environment.IsDevelopment())
            app.UseSwagger();
            app.UseSwaggerUI();
        app.UseHttpsRedirection();
        app.UseAuthorization();
        app.MapControllers();
        app.Run();
        

        上述 程式碼:

      • 加入 using 指令。
      • 將資料庫內容新增至 DI 容器。
      • 指定資料庫內容將會使用記憶體內部資料庫。
      • 生成控制器

      • 選取 [使用 Entity Framework 執行動作的 API 控制器],然後選取 [新增]

      • 在 [新增具有動作且使用 Entity Framework 的 API 控制器] 對話方塊中:

      • 在 [模型類別] 中選取 [TodoItem (TodoApi.Models)]
      • 資料內容類別中選取 TodoContext (TodoApi.Models)
      • Select Add.
      • 如果搭建操作失敗,請選取 [新增] 以嘗試再次進行搭建。

        dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design
        dotnet add package Microsoft.EntityFrameworkCore.Design
        dotnet add package Microsoft.EntityFrameworkCore.SqlServer
        dotnet add package Microsoft.EntityFrameworkCore.Tools
        dotnet tool uninstall -g dotnet-aspnet-codegenerator
        dotnet tool install -g dotnet-aspnet-codegenerator
        dotnet tool update -g dotnet-aspnet-codegenerator
        

        上述命令:

      • 新增腳手架 (Scaffolding) 所需的 NuGet 套件。
      • 在解除安裝任何可能的舊版本後,再安裝腳手架引擎 (dotnet-aspnet-codegenerator)。
      • 針對 Linux,使用下列命令將 .NET 工具目錄新增至系統路徑:

        echo 'export PATH=$HOME/.dotnet/tools:$PATH' >> ~/.bashrc
        source ~/.bashrc
        

        根據預設,要安裝的 .NET 二進位檔架構代表目前執行的 OS 架構。 若要指定不同的OS架構,請參閱 dotnet tool install, --arch 選項。 如需詳細資訊,請參閱 GitHub 問題 dotnet/AspNetCore.Docs #29262

        組建專案。

        執行以下命令:

        dotnet aspnet-codegenerator controller -name TodoItemsController -async -api -m TodoItem -dc TodoContext -outDir Controllers
        

        上述命令會生成 TodoItemsController 的框架。

        產生的程式碼:

      • 使用 [ApiController] 屬性標記類別。 這個屬性表示控制器會回應 Web API 要求。 如需屬性啟用的特定行為相關信息,請參閱 使用 ASP.NET Core 建立 Web API
      • 使用 DI 將資料庫內容 (TodoContext) 插入到控制器中。 控制器中的每一個 CRUD 方法都會使用資料庫內容。
      • ASP.NET Core 範本適用於:

      • 路由範本中檢視包含 [action] 的控制器。
      • API 控制器在路由範本中不包含 [action]
      • [action] 權杖不在路由範本中時,動作名稱 (方法名稱) 不會包含在端點中。 也就是說,動作的關聯方法名稱並未用於路由匹配。

        更新 PostTodoItem 建立方法

        更新 PostTodoItem 中的 return 陳述式,以使用 nameof 運算子:

        [HttpPost]
        public async Task<ActionResult<TodoItem>> PostTodoItem(TodoItem todoItem)
            _context.TodoItems.Add(todoItem);
            await _context.SaveChangesAsync();
            //    return CreatedAtAction("GetTodoItem", new { id = todoItem.Id }, todoItem);
            return CreatedAtAction(nameof(GetTodoItem), new { id = todoItem.Id }, todoItem);
        

        上述程式碼是 HTTP POST 方法,以 [HttpPost] 屬性表示。 該方法會從 HTTP 要求本文取得 TodoItem 的值。

        如需詳細資訊,請參閱 使用 Http[Verb] 屬性的屬性路由

        CreatedAtAction 方法:

      • 如果成功,會傳回 HTTP 201 狀態代碼 。 對於可在伺服器上建立新資源的 HTTP 201 方法,HTTP POST 是標準回應。
      • Location標頭新增到回應。 Location 標頭會指定新建待辦事項的 URI。 如需詳細資訊,請參閱 10.2.2 201 已建立
      • 參考 GetTodoItem 動作以建立 Location 標頭的 URI。 C# nameof 關鍵字是用來避免在 CreatedAtAction 呼叫中以硬式編碼方式寫入動作名稱。
      • Test PostTodoItem

      • 按 Ctrl+F5 執行應用程式。

      • 在 Swagger 瀏覽器視窗中,選取 [POST /api/TodoItems],然後選取 [試用]

      • 請求主體 輸入視窗中,更新 JSON。 For example,

        "name": "walk dog", "isComplete": true
      • Select Execute

        測試位置標頭中的 URI

        在上述 POST 中,Swagger UI 會在回應標頭底下顯示位置標頭。 例如: location: https://localhost:7260/api/TodoItems/1 。 位置標頭會顯示所建立資源的 URI。

        若要測試位置標頭:

      • 在 Swagger 瀏覽器視窗中,選取 [GET /api/TodoItems/{id}],然後選取 [試用]

      • 1 輸入方塊中輸入 id,然後選取 [執行]

        上一節顯示 /api/todoitems/{id} 路由的範例。

        依照 POST 指示新增另一個待辦事項,然後使用 Swagger 測試 /api/todoitems 路由。

        這個應用程式會使用記憶體內部資料庫。 如果應用程式在停止後再啟動,上述 GET 要求不會傳回任何資料。 如果未傳回任何數據,請將 POST 資料傳送至應用程式。

        路由和 URL 路徑

        [HttpGet] 屬性代表回應 HTTP GET 要求的方法。 每個方法的 URL 路徑的建構方式如下:

      • 一開始在控制器的 Route 屬性中使用範本字串:

        [Route("api/[controller]")]
        [ApiController]
        public class TodoItemsController : ControllerBase
        
      • 以控制器的名稱取代 [controller],也就是將控制器類別名稱減去 "Controller" 字尾。 在此範例中,控制器類別名稱是 TodoItemsController,因此控制器名稱是 "TodoItems"。 ASP.NET 核心 路由 不區分大小寫。

      • 如果 [HttpGet] 屬性具有路由範本 (例如 [HttpGet("products")]),請將其附加到路徑。 此範例不使用範本。 如需詳細資訊,請參閱 使用 Http[Verb] 屬性的屬性路由

        在下列 GetTodoItem 方法中,"{id}" 是待辦事項唯一識別碼的預留位置變數。 在叫用 GetTodoItem 時,會將 URL 中的 "{id}" 值提供給方法的 id 參數。

        [HttpGet("{id}")]
        public async Task<ActionResult<TodoItem>> GetTodoItem(long id)
            var todoItem = await _context.TodoItems.FindAsync(id);
            if (todoItem == null)
                return NotFound();
            return todoItem;
        

        Return values

        GetTodoItemsGetTodoItem 方法的傳回類型為 ActionResult<T> 類型。 ASP.NET Core 會自動將物件序列化為 JSON,並將 JSON 寫入至回應訊息的本文。 此傳回類型的回應碼為 200 OK,假設沒有未處理的例外狀況。 未處理的例外狀況會轉譯成 5xx 錯誤。

        ActionResult 傳回型別可代表各種 HTTP 狀態碼。 例如,GetTodoItem 可傳回兩個不同的狀態值:

      • 如果沒有項目符合所要求的識別碼,方法會傳回 404 狀態NotFound 錯誤碼。
      • 否則,該方法會傳回 200 並包含 JSON 回應主體。 傳回 item 結果將得到 HTTP 200 回應。
      • PutTodoItem 方法

        檢查 PutTodoItem 方法:

        [HttpPut("{id}")]
        public async Task<IActionResult> PutTodoItem(long id, TodoItem todoItem)
            if (id != todoItem.Id)
                return BadRequest();
            _context.Entry(todoItem).State = EntityState.Modified;
                await _context.SaveChangesAsync();
            catch (DbUpdateConcurrencyException)
                if (!TodoItemExists(id))
                    return NotFound();
                    throw;
            return NoContent();
                      PutTodoItem 類似於 PostTodoItem,但是會使用 HTTP PUT。 回應為 204(無內容)。 根據 HTTP 規格,PUT 要求用戶端傳送完整更新的實體,而不只是變更。 若要支援部分更新,請使用 HTTP PATCH

        測試 PutTodoItem 方法

        每次啟動應用程式時,此範例使用的記憶體內部資料庫必須被初始化。 資料庫中必須有項目,您才能進行 PUT 呼叫。 在發出 PUT 呼叫之前,呼叫 GET 以確保資料庫中有項目。

        使用 Swagger UI,使用 PUT 按鈕來更新識別碼為 1 的 TodoItem,並將其名稱設定為 "feed fish"。 請注意,回應為 HTTP 204 No Content

        DeleteTodoItem 方法

        檢查 DeleteTodoItem 方法:

        [HttpDelete("{id}")]
        public async Task<IActionResult> DeleteTodoItem(long id)
            var todoItem = await _context.TodoItems.FindAsync(id);
            if (todoItem == null)
                return NotFound();
            _context.TodoItems.Remove(todoItem);
            await _context.SaveChangesAsync();
            return NoContent();
        

        測試 DeleteTodoItem 方法

        使用 Swagger UI 刪除識別碼為 1 的 TodoItem。 請注意,回應為 HTTP 204 No Content

        使用其他工具進行測試

        還有其他許多工具可用來測試 Web API,例如:

        Visual Studio 端點總管和 .http 檔案
      • http-repl
      • curl. Swagger 會使用 curl 並顯示其提交的 curl 命令。 Fiddler

        如需詳細資訊,請參閱

        最低 API 教學課程:使用 .HTTP 檔案和端點總管進行測試

        Prevent over-posting

        目前範例應用程式會公開整個 TodoItem 物件。 生產應用程式通常會限制輸入的資料,並使用模型的子集傳回。 背後有多個原因,而安全性是主要原因。 模型的子集通常稱為資料傳輸物件 (DTO)、輸入模型或檢視模型。 本教學課程中使用 DTO

        DTO 可以用來:

      • Prevent over-posting.
      • 隱藏用戶端不應該檢視的屬性。
      • 省略一些屬性,以減少承載大小。
      • 將包含巢狀物件的物件圖扁平化。 扁平化的物件圖譜可能對客戶端來說更加方便。
      • 若要示範 DTO 方法,請更新 TodoItem 類別以包含祕密欄位:

        namespace TodoApi.Models
            public class TodoItem
                public long Id { get; set; }
                public string? Name { get; set; }
                public bool IsComplete { get; set; }
                public string? Secret { get; set; }
        

        必須將祕密欄位從此應用程式中隱藏,但管理應用程式可以選擇顯示它。

        驗證您可以提交並取得隱私欄位。

        建立 DTO 模型:

        namespace TodoApi.Models;
        public class TodoItemDTO
            public long Id { get; set; }
            public string? Name { get; set; }
            public bool IsComplete { get; set; }
        

        更新 TodoItemsController 以使用 TodoItemDTO

        using Microsoft.AspNetCore.Mvc;
        using Microsoft.EntityFrameworkCore;
        using TodoApi.Models;
        namespace TodoApi.Controllers;
        [Route("api/[controller]")]
        [ApiController]
        public class TodoItemsController : ControllerBase
            private readonly TodoContext _context;
            public TodoItemsController(TodoContext context)
                _context = context;
            // GET: api/TodoItems
            [HttpGet]
            public async Task<ActionResult<IEnumerable<TodoItemDTO>>> GetTodoItems()
                return await _context.TodoItems
                    .Select(x => ItemToDTO(x))
                    .ToListAsync();
            // GET: api/TodoItems/5
            // <snippet_GetByID>
            [HttpGet("{id}")]
            public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
                var todoItem = await _context.TodoItems.FindAsync(id);
                if (todoItem == null)
                    return NotFound();
                return ItemToDTO(todoItem);
            // </snippet_GetByID>
            // PUT: api/TodoItems/5
            // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
            // <snippet_Update>
            [HttpPut("{id}")]
            public async Task<IActionResult> PutTodoItem(long id, TodoItemDTO todoDTO)
                if (id != todoDTO.Id)
                    return BadRequest();
                var todoItem = await _context.TodoItems.FindAsync(id);
                if (todoItem == null)
                    return NotFound();
                todoItem.Name = todoDTO.Name;
                todoItem.IsComplete = todoDTO.IsComplete;
                    await _context.SaveChangesAsync();
                catch (DbUpdateConcurrencyException) when (!TodoItemExists(id))
                    return NotFound();
                return NoContent();
            // </snippet_Update>
            // POST: api/TodoItems
            // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
            // <snippet_Create>
            [HttpPost]
            public async Task<ActionResult<TodoItemDTO>> PostTodoItem(TodoItemDTO todoDTO)
                var todoItem = new TodoItem
                    IsComplete = todoDTO.IsComplete,
                    Name = todoDTO.Name
                _context.TodoItems.Add(todoItem);
                await _context.SaveChangesAsync();
                return CreatedAtAction(
                    nameof(GetTodoItem),
                    new { id = todoItem.Id },
                    ItemToDTO(todoItem));
            // </snippet_Create>
            // DELETE: api/TodoItems/5
            [HttpDelete("{id}")]
            public async Task<IActionResult> DeleteTodoItem(long id)
                var todoItem = await _context.TodoItems.FindAsync(id);
                if (todoItem == null)
                    return NotFound();
                _context.TodoItems.Remove(todoItem);
                await _context.SaveChangesAsync();
                return NoContent();
            private bool TodoItemExists(long id)
                return _context.TodoItems.Any(e => e.Id == id);
            private static TodoItemDTO ItemToDTO(TodoItem todoItem) =>
               new TodoItemDTO
                   Id = todoItem.Id,
                   Name = todoItem.Name,
                   IsComplete = todoItem.IsComplete
        

        確認您無法張貼或取得祕密欄位。

        使用 JavaScript 呼叫 Web API

        請參閱 教學課程:使用 JavaScript 呼叫 ASP.NET Core Web API

        Web API 影片系列

        請參閱 影片:初學者系列 — 網頁 API

        企業 Web 應用程式模式

        如需建立可靠、安全、高效能、可測試且可調整 ASP.NET 核心應用程式的指引,請參閱 企業 Web 應用程式模式。 提供可實作模式的完整生產品質範例 Web 應用程式。

        將驗證支援新增至 Web API

        ASP.NET Core Identity 會將使用者介面 (UI) 登入功能新增至 ASP.NET Core Web 應用程式。 若要保護 Web API 和 SPA,請使用下列其中一項:

        Microsoft Entra 身份識別 Azure Active Directory B2C (Azure AD B2C) Duende Identity 伺服器

        Duende Identity 伺服器是適用於 ASP.NET Core 的 OpenID Connect 和 OAuth 2.0 架構。 Duende Identity 伺服器會啟用下列安全性功能:

      • 驗證即服務 (AaaS)
      • 多個應用程式類型的單一登入/登出 (SSO)
      • API 的存取控制
      • Federation Gateway
      • Important

        Duende Software 可能會要求您支付授權費用才能在生產環境中使用 Duende Identity 伺服器。 如需詳細資訊,請參閱 從 .NET 5 中的 ASP.NET Core 移轉至 .NET 6

        如需詳細資訊,請參閱 Duende 伺服器檔(Duende Identity Software 網站)。

        發佈至 Azure

        如需部署至 Azure 的資訊,請參閱 快速入門:部署 ASP.NET Web 應用程式

        Additional resources

        檢視或下載本教學課程的範例程序代碼。 請參閱 如何下載

        如需詳細資訊,請參閱以下資源:

        使用 ASP.NET Core 建立 Web API 教學課程:使用 ASP.NET Core 建立最小 API ASP.NET Core Web API 文件,使用 Swagger / OpenAPI Razor 在 ASP.NET Core 中控制器動作的路由配置 ASP.NET Core Web API 中的控制器動作傳回類型 將 ASP.NET Core 應用程式部署至 Azure App Service 裝載和部署 ASP.NET Core 使用 ASP.NET Core 建立 Web API

        本教學課程將教導建置使用資料庫之控制器型 Web API 的基本概念。 在 ASP.NET Core 中建立 API 的另一種方法是建立最小的 API。 如需在最小 API 與控制器型 API 之間進行選擇的協助,請參閱 API 概觀。 如需建立最小 API 的教學課程,請參閱 教學課程:使用 ASP.NET Core 建立最小 API

        Overview

        本教學課程會建立以下 API:

        Description Request body Response body .NET 8 SDK

        Visual Studio Code 指示針對 ASP.NET Core 開發函式 (例如專案建立) 使用 .NET CLI。 您可以在 macOS、Linux 或 Windows 以及任何程式碼編輯器中遵循這些指示。 如果您使用 Visual Studio Code 以外的工具,可能需要進行微幅變更。

        建立 Web 專案

      • 在搜尋方塊中輸入 Web API
      • 選取 [ASP.NET Core Web API 範本],然後選取 [ 下一步]。
      • 在 [ 設定新專案] 對話框中,將專案命名為 TodoApi ,然後選取 [ 下一步]。
      • 在 [其他資訊] 對話方塊中:
        • 確認 Framework.NET 8.0 (長期支援)
        • 確認已勾選 [使用控制器] 複選框(若取消勾選,將使用最少 API)
        • 確認已核取 [啟用 OpenAPI 支援 ] 複選框。
        • Select Create.
        • 新增 NuGet 套件

          必須新增 NuGet 套件,才能支援本教學課程中使用的資料庫。

        • 在 [工具] 功能表上,選取 [NuGet 套件管理員] > [管理解決方案的 NuGet 套件]
        • 選取瀏覽 索引標籤。
        • 在搜尋方塊中輸入 Microsoft.EntityFrameworkCore.InMemory,然後選取 Microsoft.EntityFrameworkCore.InMemory
        • 選取右窗格中的 [專案] 核取方塊,然後選取 [安裝]
        • dotnet new webapi --use-controllers -o TodoApi
          cd TodoApi
          dotnet add package Microsoft.EntityFrameworkCore.InMemory
          code -r ../TodoApi
          

          These commands:

        • 建立新的 Web API 專案,然後在 Visual Studio Code 中予以開啟。
        • 新增下一節所需的 NuGet 套件。
        • 在 Visual Studio Code 的目前實例中開啟 TodoApi 資料夾。
        • Visual Studio Code 可能會顯示一個對話框,詢問: 您信任此資料夾中檔案的作者嗎?

        • 如果您信任父資料夾中的所有檔案,請選取 [信任父資料夾中所有檔案的作者]
        • 選取 [是,信任作者],因為專案資料夾有 .NET 產生的檔案。
        • 當 Visual Studio Code 要求您新增資產以建置和偵錯專案時,請選取 [是]。 如果 Visual Studio Code 不提供新增建置和偵錯資產,請選取 [檢視]>[命令選擇區],然後在搜尋方塊中輸入「.NET」。 從命令清單中選取 .NET: Generate Assets for Build and Debug 命令。
        • Visual Studio Code 會新增 .vscode 資料夾,其中包含產生的 launch.jsontasks.json 檔案。

          上述命令需要Linux上的.NET 9或更新版本 SDK。 針對 .NET 8.0.401 或更早版本的 SDK 上的 Linux,請參閱 Linux 發行版的文件以建立憑證信任。

          若憑證先前不受信任,則上述命令會顯示下列對話方塊:

          Ctrl+按一下輸出中的 HTTPS URL,以在瀏覽器中測試 Web 應用程式。

        • 預設瀏覽器會啟動至 https://localhost:<port>/swagger/index.html,其中 <port> 是輸出中顯示的隨機選擇連接埠號碼。 在 https://localhost:<port>,沒有端點,因此瀏覽器會回傳 HTTP 404 找不到。 附加 /swagger 至 URL https://localhost:<port>/swagger

          在下列指示中測試 Web 應用程式之後,請在整合式終端機中按 Ctrl+C 以將其關機。

          Swagger 頁面 /swagger/index.html 隨即顯示。 選取 GET>試試看>執行。 頁面會顯示:

        • 用來測試 WeatherForecast API 的 Curl 命令。
        • 用來測試 WeatherForecast API 的 URL。
        • 回應碼、本文和標頭。
        • 具有媒體類型與範例值和架構的下拉式清單方塊。
        • 如果 Swagger 頁面未出現,請參閱 此 GitHub 問題

          Swagger 可用來為 Web API 產生有用的文件和說明頁面。 本教學課程會使用 Swagger 來測試應用程式。 如需 Swagger 的詳細資訊,請參閱 使用 Swagger / OpenAPI ASP.NET Core Web API 檔

          複製並貼上瀏覽器中的要求 URLhttps://localhost:<port>/weatherforecast

          系統會傳回類似下列範例的 JSON:

          "date": "2019-07-16T19:04:05.7257911-06:00", "temperatureC": 52, "temperatureF": 125, "summary": "Mild" "date": "2019-07-17T19:04:05.7258461-06:00", "temperatureC": 36, "temperatureF": 96, "summary": "Warm" "date": "2019-07-18T19:04:05.7258467-06:00", "temperatureC": 39, "temperatureF": 102, "summary": "Cool" "date": "2019-07-19T19:04:05.7258471-06:00", "temperatureC": 10, "temperatureF": 49, "summary": "Bracing" "date": "2019-07-20T19:04:05.7258474-06:00", "temperatureC": -1, "temperatureF": 31, "summary": "Chilly"

          新增模型類別

          「模型」是代表應用程式所管理資料的一組類別。 此應用程式的模型是 TodoItem 類別。

        • [方案總管] 中,用滑鼠右鍵點擊專案。 選擇 新增>新資料夾。 將資料夾命名為 Models
        • 以滑鼠右鍵按一下 Models 資料夾並選取 [新增]>[類別]。 將類別命名為 TodoItem ,然後選取 [ 新增]。
        • 以下列項目取代範本程式碼:
        • public long Id { get; set; } public string? Name { get; set; } public bool IsComplete { get; set; } Id 屬性的功能相當於關聯式資料庫中的唯一索引鍵。

          模型類別可位於專案中的任何位置,但依照慣例會使用 Models 資料夾。

          新增資料庫上下文

          「資料庫內容」是為資料模型協調 Entity Framework 功能的主要類別。 此類別是透過衍生自 Microsoft.EntityFrameworkCore.DbContext 類別來建立。

          public class TodoContext : DbContext public TodoContext(DbContextOptions<TodoContext> options) : base(options) public DbSet<TodoItem> TodoItems { get; set; } = null!;

          登錄資料庫內容

          在 ASP.NET Core 中,DB 內容之類的服務必須向 相依性插入 (DI) 容器註冊。 此容器會將服務提供給控制器。

          使用下列醒目的程式碼更新 Program.cs

          using Microsoft.EntityFrameworkCore;
          using TodoApi.Models;
          var builder = WebApplication.CreateBuilder(args);
          builder.Services.AddControllers();
          builder.Services.AddDbContext<TodoContext>(opt =>
              opt.UseInMemoryDatabase("TodoList"));
          builder.Services.AddEndpointsApiExplorer();
          builder.Services.AddSwaggerGen();
          var app = builder.Build();
          if (app.Environment.IsDevelopment())
              app.UseSwagger();
              app.UseSwaggerUI();
          app.UseHttpsRedirection();
          app.UseAuthorization();
          app.MapControllers();
          app.Run();
          

          上述 程式碼:

        • 加入 using 指令。
        • 將資料庫內容新增至 DI 容器。
        • 指定資料庫內容將會使用記憶體內部資料庫。
        • 生成控制器

        • 選取 [使用 Entity Framework 執行動作的 API 控制器],然後選取 [新增]

        • 在 [新增具有動作且使用 Entity Framework 的 API 控制器] 對話方塊中:

        • 在 [模型類別] 中選取 [TodoItem (TodoApi.Models)]
        • 資料內容類別中選取 TodoContext (TodoApi.Models)
        • Select Add.
        • 如果搭建操作失敗,請選取 [新增] 以嘗試再次進行搭建。

          dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design
          dotnet add package Microsoft.EntityFrameworkCore.Design
          dotnet add package Microsoft.EntityFrameworkCore.SqlServer
          dotnet add package Microsoft.EntityFrameworkCore.Tools
          dotnet tool uninstall -g dotnet-aspnet-codegenerator
          dotnet tool install -g dotnet-aspnet-codegenerator
          dotnet tool update -g dotnet-aspnet-codegenerator
          

          上述命令:

        • 新增腳手架 (Scaffolding) 所需的 NuGet 套件。
        • 在解除安裝任何可能的舊版本後,再安裝腳手架引擎 (dotnet-aspnet-codegenerator)。
        • 針對 Linux,使用下列命令將 .NET 工具目錄新增至系統路徑:

          echo 'export PATH=$HOME/.dotnet/tools:$PATH' >> ~/.bashrc
          source ~/.bashrc
          

          根據預設,要安裝的 .NET 二進位檔架構代表目前執行的 OS 架構。 若要指定不同的OS架構,請參閱 dotnet tool install, --arch 選項。 如需詳細資訊,請參閱 GitHub 問題 dotnet/AspNetCore.Docs #29262

          組建專案。

          執行以下命令:

          dotnet aspnet-codegenerator controller -name TodoItemsController -async -api -m TodoItem -dc TodoContext -outDir Controllers
          

          上述命令會生成 TodoItemsController 的框架。

          產生的程式碼:

        • 使用 [ApiController] 屬性標記類別。 這個屬性表示控制器會回應 Web API 要求。 如需屬性啟用的特定行為相關信息,請參閱 使用 ASP.NET Core 建立 Web API
        • 使用 DI 將資料庫內容 (TodoContext) 插入到控制器中。 控制器中的每一個 CRUD 方法都會使用資料庫內容。
        • ASP.NET Core 範本適用於:

        • 路由範本中檢視包含 [action] 的控制器。
        • API 控制器在路由範本中不包含 [action]
        • [action] 權杖不在路由範本中時,動作名稱 (方法名稱) 不會包含在端點中。 也就是說,動作的關聯方法名稱並未用於路由匹配。

          更新 PostTodoItem 建立方法

          更新 PostTodoItem 中的 return 陳述式,以使用 nameof 運算子:

          [HttpPost]
          public async Task<ActionResult<TodoItem>> PostTodoItem(TodoItem todoItem)
              _context.TodoItems.Add(todoItem);
              await _context.SaveChangesAsync();
              //    return CreatedAtAction("GetTodoItem", new { id = todoItem.Id }, todoItem);
              return CreatedAtAction(nameof(GetTodoItem), new { id = todoItem.Id }, todoItem);
          

          上述程式碼是 HTTP POST 方法,以 [HttpPost] 屬性表示。 該方法會從 HTTP 要求本文取得 TodoItem 的值。

          如需詳細資訊,請參閱 使用 Http[Verb] 屬性的屬性路由

          CreatedAtAction 方法:

        • 如果成功,會傳回 HTTP 201 狀態代碼 。 對於可在伺服器上建立新資源的 HTTP 201 方法,HTTP POST 是標準回應。
        • Location標頭新增到回應。 Location 標頭會指定新建待辦事項的 URI。 如需詳細資訊,請參閱 10.2.2 201 已建立
        • 參考 GetTodoItem 動作以建立 Location 標頭的 URI。 C# nameof 關鍵字是用來避免在 CreatedAtAction 呼叫中以硬式編碼方式寫入動作名稱。
        • Test PostTodoItem

        • 按 Ctrl+F5 執行應用程式。

        • 在 Swagger 瀏覽器視窗中,選取 [POST /api/TodoItems],然後選取 [試用]

        • 請求主體 輸入視窗中,更新 JSON。 For example,

          "name": "walk dog", "isComplete": true
        • Select Execute

          測試位置標頭中的 URI

          在上述 POST 中,Swagger UI 會在回應標頭底下顯示位置標頭。 例如: location: https://localhost:7260/api/TodoItems/1 。 位置標頭會顯示所建立資源的 URI。

          若要測試位置標頭:

        • 在 Swagger 瀏覽器視窗中,選取 [GET /api/TodoItems/{id}],然後選取 [試用]

        • 1 輸入方塊中輸入 id,然後選取 [執行]

          上一節顯示 /api/todoitems/{id} 路由的範例。

          依照 POST 指示新增另一個待辦事項,然後使用 Swagger 測試 /api/todoitems 路由。

          這個應用程式會使用記憶體內部資料庫。 如果應用程式在停止後再啟動,上述 GET 要求不會傳回任何資料。 如果未傳回任何數據,請將 POST 資料傳送至應用程式。

          路由和 URL 路徑

          [HttpGet] 屬性代表回應 HTTP GET 要求的方法。 每個方法的 URL 路徑的建構方式如下:

        • 一開始在控制器的 Route 屬性中使用範本字串:

          [Route("api/[controller]")]
          [ApiController]
          public class TodoItemsController : ControllerBase
          
        • 以控制器的名稱取代 [controller],也就是將控制器類別名稱減去 "Controller" 字尾。 在此範例中,控制器類別名稱是 TodoItemsController,因此控制器名稱是 "TodoItems"。 ASP.NET 核心 路由 不區分大小寫。

        • 如果 [HttpGet] 屬性具有路由範本 (例如 [HttpGet("products")]),請將其附加到路徑。 此範例不使用範本。 如需詳細資訊,請參閱 使用 Http[Verb] 屬性的屬性路由

          在下列 GetTodoItem 方法中,"{id}" 是待辦事項唯一識別碼的預留位置變數。 在叫用 GetTodoItem 時,會將 URL 中的 "{id}" 值提供給方法的 id 參數。

          [HttpGet("{id}")]
          public async Task<ActionResult<TodoItem>> GetTodoItem(long id)
              var todoItem = await _context.TodoItems.FindAsync(id);
              if (todoItem == null)
                  return NotFound();
              return todoItem;
          

          Return values

          GetTodoItemsGetTodoItem 方法的傳回類型為 ActionResult<T> 類型。 ASP.NET Core 會自動將物件序列化為 JSON,並將 JSON 寫入至回應訊息的本文。 此傳回類型的回應碼為 200 OK,假設沒有未處理的例外狀況。 未處理的例外狀況會轉譯成 5xx 錯誤。

          ActionResult 傳回型別可代表各種 HTTP 狀態碼。 例如,GetTodoItem 可傳回兩個不同的狀態值:

        • 如果沒有項目符合所要求的識別碼,方法會傳回 404 狀態NotFound 錯誤碼。
        • 否則,該方法會傳回 200 並包含 JSON 回應主體。 傳回 item 結果將得到 HTTP 200 回應。
        • PutTodoItem 方法

          檢查 PutTodoItem 方法:

          [HttpPut("{id}")]
          public async Task<IActionResult> PutTodoItem(long id, TodoItem todoItem)
              if (id != todoItem.Id)
                  return BadRequest();
              _context.Entry(todoItem).State = EntityState.Modified;
                  await _context.SaveChangesAsync();
              catch (DbUpdateConcurrencyException)
                  if (!TodoItemExists(id))
                      return NotFound();
                      throw;
              return NoContent();
                        PutTodoItem 類似於 PostTodoItem,但是會使用 HTTP PUT。 回應為 204(無內容)。 根據 HTTP 規格,PUT 要求用戶端傳送完整更新的實體,而不只是變更。 若要支援部分更新,請使用 HTTP PATCH

          測試 PutTodoItem 方法

          每次啟動應用程式時,此範例使用的記憶體內部資料庫必須被初始化。 資料庫中必須有項目,您才能進行 PUT 呼叫。 在發出 PUT 呼叫之前,呼叫 GET 以確保資料庫中有項目。

          使用 Swagger UI,使用 PUT 按鈕來更新識別碼為 1 的 TodoItem,並將其名稱設定為 "feed fish"。 請注意,回應為 HTTP 204 No Content

          DeleteTodoItem 方法

          檢查 DeleteTodoItem 方法:

          [HttpDelete("{id}")]
          public async Task<IActionResult> DeleteTodoItem(long id)
              var todoItem = await _context.TodoItems.FindAsync(id);
              if (todoItem == null)
                  return NotFound();
              _context.TodoItems.Remove(todoItem);
              await _context.SaveChangesAsync();
              return NoContent();
          

          測試 DeleteTodoItem 方法

          使用 Swagger UI 刪除識別碼為 1 的 TodoItem。 請注意,回應為 HTTP 204 No Content

          使用其他工具進行測試

          還有其他許多工具可用來測試 Web API,例如:

          Visual Studio 端點總管和 .http 檔案
        • http-repl curl. Swagger 會使用 curl 並顯示其提交的 curl 命令。 Fiddler

          如需詳細資訊,請參閱

          最低 API 教學課程:使用 .HTTP 檔案和端點總管進行測試

          Prevent over-posting

          目前範例應用程式會公開整個 TodoItem 物件。 生產應用程式通常會限制輸入的資料,並使用模型的子集傳回。 背後有多個原因,而安全性是主要原因。 模型的子集通常稱為資料傳輸物件 (DTO)、輸入模型或檢視模型。 本教學課程中使用 DTO

          DTO 可以用來:

        • Prevent over-posting.
        • 隱藏用戶端不應該檢視的屬性。
        • 省略一些屬性,以減少承載大小。
        • 將包含巢狀物件的物件圖扁平化。 扁平化的物件圖譜可能對客戶端來說更加方便。
        • 若要示範 DTO 方法,請更新 TodoItem 類別以包含祕密欄位:

          namespace TodoApi.Models
              public class TodoItem
                  public long Id { get; set; }
                  public string? Name { get; set; }
                  public bool IsComplete { get; set; }
                  public string? Secret { get; set; }
          

          必須將祕密欄位從此應用程式中隱藏,但管理應用程式可以選擇顯示它。

          驗證您可以提交並取得隱私欄位。

          建立 DTO 模型:

          namespace TodoApi.Models;
          public class TodoItemDTO
              public long Id { get; set; }
              public string? Name { get; set; }
              public bool IsComplete { get; set; }
          

          更新 TodoItemsController 以使用 TodoItemDTO

          using Microsoft.AspNetCore.Mvc;
          using Microsoft.EntityFrameworkCore;
          using TodoApi.Models;
          namespace TodoApi.Controllers;
          [Route("api/[controller]")]
          [ApiController]
          public class TodoItemsController : ControllerBase
              private readonly TodoContext _context;
              public TodoItemsController(TodoContext context)
                  _context = context;
              // GET: api/TodoItems
              [HttpGet]
              public async Task<ActionResult<IEnumerable<TodoItemDTO>>> GetTodoItems()
                  return await _context.TodoItems
                      .Select(x => ItemToDTO(x))
                      .ToListAsync();
              // GET: api/TodoItems/5
              // <snippet_GetByID>
              [HttpGet("{id}")]
              public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
                  var todoItem = await _context.TodoItems.FindAsync(id);
                  if (todoItem == null)
                      return NotFound();
                  return ItemToDTO(todoItem);
              // </snippet_GetByID>
              // PUT: api/TodoItems/5
              // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
              // <snippet_Update>
              [HttpPut("{id}")]
              public async Task<IActionResult> PutTodoItem(long id, TodoItemDTO todoDTO)
                  if (id != todoDTO.Id)
                      return BadRequest();
                  var todoItem = await _context.TodoItems.FindAsync(id);
                  if (todoItem == null)
                      return NotFound();
                  todoItem.Name = todoDTO.Name;
                  todoItem.IsComplete = todoDTO.IsComplete;
                      await _context.SaveChangesAsync();
                  catch (DbUpdateConcurrencyException) when (!TodoItemExists(id))
                      return NotFound();
                  return NoContent();
              // </snippet_Update>
              // POST: api/TodoItems
              // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
              // <snippet_Create>
              [HttpPost]
              public async Task<ActionResult<TodoItemDTO>> PostTodoItem(TodoItemDTO todoDTO)
                  var todoItem = new TodoItem
                      IsComplete = todoDTO.IsComplete,
                      Name = todoDTO.Name
                  _context.TodoItems.Add(todoItem);
                  await _context.SaveChangesAsync();
                  return CreatedAtAction(
                      nameof(GetTodoItem),
                      new { id = todoItem.Id },
                      ItemToDTO(todoItem));
              // </snippet_Create>
              // DELETE: api/TodoItems/5
              [HttpDelete("{id}")]
              public async Task<IActionResult> DeleteTodoItem(long id)
                  var todoItem = await _context.TodoItems.FindAsync(id);
                  if (todoItem == null)
                      return NotFound();
                  _context.TodoItems.Remove(todoItem);
                  await _context.SaveChangesAsync();
                  return NoContent();
              private bool TodoItemExists(long id)
                  return _context.TodoItems.Any(e => e.Id == id);
              private static TodoItemDTO ItemToDTO(TodoItem todoItem) =>
                 new TodoItemDTO
                     Id = todoItem.Id,
                     Name = todoItem.Name,
                     IsComplete = todoItem.IsComplete
          

          確認您無法張貼或取得祕密欄位。

          使用 JavaScript 呼叫 Web API

          請參閱 教學課程:使用 JavaScript 呼叫 ASP.NET Core Web API

          Web API 影片系列

          請參閱 影片:初學者系列 — 網頁 API

          企業 Web 應用程式模式

          如需建立可靠、安全、高效能、可測試且可調整 ASP.NET 核心應用程式的指引,請參閱 企業 Web 應用程式模式。 提供可實作模式的完整生產品質範例 Web 應用程式。

          將驗證支援新增至 Web API

          ASP.NET Core Identity 會將使用者介面 (UI) 登入功能新增至 ASP.NET Core Web 應用程式。 若要保護 Web API 和 SPA,請使用下列其中一項:

          Microsoft Entra 身份識別 Azure Active Directory B2C (Azure AD B2C) Duende Identity 伺服器

          Duende Identity 伺服器是適用於 ASP.NET Core 的 OpenID Connect 和 OAuth 2.0 架構。 Duende Identity 伺服器會啟用下列安全性功能:

        • 驗證即服務 (AaaS)
        • 多個應用程式類型的單一登入/登出 (SSO)
        • API 的存取控制
        • Federation Gateway
        • Important

          Duende Software 可能會要求您支付授權費用才能在生產環境中使用 Duende Identity 伺服器。 如需詳細資訊,請參閱 從 .NET 5 中的 ASP.NET Core 移轉至 .NET 6

          如需詳細資訊,請參閱 Duende 伺服器檔(Duende Identity Software 網站)。

          發佈至 Azure

          如需部署至 Azure 的資訊,請參閱 快速入門:部署 ASP.NET Web 應用程式

          Additional resources

          檢視或下載本教學課程的範例程序代碼。 請參閱 如何下載

          如需詳細資訊,請參閱以下資源:

          使用 ASP.NET Core 建立 Web API 教學課程:使用 ASP.NET Core 建立最小 API ASP.NET Core Web API 文件,使用 Swagger / OpenAPI Razor 在 ASP.NET Core 中控制器動作的路由配置 ASP.NET Core Web API 中的控制器動作傳回類型 將 ASP.NET Core 應用程式部署至 Azure App Service 裝載和部署 ASP.NET Core 使用 ASP.NET Core 建立 Web API
  •