教學課程:使用 ASP.NET Core 建立 Web APITutorial: Create a web API with ASP.NET Core

Rick AndersonMike Wasson 提供By Rick Anderson and Mike Wasson

本教學課程將教導您使用 ASP.NET Core 建立 Web API 的基本概念。This tutorial teaches the basics of building a web API with ASP.NET Core.

在本教學課程中,您將了解如何:In this tutorial, you learn how to:

  • 建立 Web API 專案。Create a web API project.
  • 新增模型類別和資料庫內容。Add a model class and a database context.
  • 使用 CRUD 方法 Scaffold 控制器。Scaffold a controller with CRUD methods.
  • 設定路由、URL 路徑和傳回值。Configure routing, URL paths, and return values.
  • 使用 Postman 呼叫 Web API。Call the web API with Postman.

結束時,您會有一個 Web API,可以管理儲存在資料庫中的「待辦事項」。At the end, you have a web API that can manage "to-do" items stored in a database.

概觀Overview

本教學課程會建立以下 API:This tutorial creates the following API:

APIAPI 描述Description 要求本文Request body 回應本文Response body
GET /api/TodoItemsGET /api/TodoItems 取得所有待辦事項Get all to-do items NoneNone 待辦事項的陣列Array of to-do items
GET /api/TodoItems/{識別碼}GET /api/TodoItems/{id} 依識別碼取得項目Get an item by ID NoneNone 待辦事項To-do item
POST /api/TodoItemsPOST /api/TodoItems 新增記錄Add a new item 待辦事項To-do item 待辦事項To-do item
PUT /api/TodoItems/{識別碼}PUT /api/TodoItems/{id} 更新現有的項目  Update an existing item   待辦事項To-do item NoneNone
刪除/api/TodoItems/{id}    DELETE /api/TodoItems/{id}         刪除專案Delete an item     NoneNone NoneNone

下圖顯示應用程式的設計。The following diagram shows the design of the app.

左側方塊代表用戶端。

必要條件:Prerequisites

建立 Web 專案Create a web project

  • 從 [檔案] 功能表中,選取 [新增>專案]。From the File menu, select New > Project.
  • 選取 ASP.NET Core Web 應用程式範本,然後按一下 [下一步]。Select the ASP.NET Core Web Application template and click Next.
  • 將專案命名為 TodoApi,然後按一下 [建立]。Name the project TodoApi and click Create.
  • 在 [建立新的 ASP.NET Core Web 應用程式] 對話方塊中,確認已選取 [ .net Core ] 和 [ ASP.NET Core 3.1 ]。In the Create a new ASP.NET Core Web Application dialog, confirm that .NET Core and ASP.NET Core 3.1 are selected. 選取 API 範本,然後按一下 [建立]。Select the API template and click Create.

VS 新增專案對話方塊

測試 APITest the API

專案範本會建立 WeatherForecast API。The project template creates a WeatherForecast API. 從瀏覽器呼叫 Get 方法來測試應用程式。Call the Get method from a browser to test the app.

按 Ctrl+F5 執行應用程式。Press Ctrl+F5 to run the app. Visual Studio 會啟動瀏覽器並巡覽至 https://localhost:<port>/WeatherForecast,其中 <port> 是隨機選擇的通訊埠編號。Visual Studio launches a browser and navigates to https://localhost:<port>/WeatherForecast, where <port> is a randomly chosen port number.

如果出現對話方塊詢問您是否應該信任 IIS Express 憑證,請選取 [是]。If you get a dialog box that asks if you should trust the IIS Express certificate, select Yes. 在接著出現的 [安全性警告] 對話方塊中,選取 [是]。In the Security Warning dialog that appears next, select Yes.

系統會傳回與下列類似的 JSON:JSON similar to the following is returned:

[
    {
        "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"
    }
]

新增模型類別Add a model class

「模型」是代表應用程式所管理資料的一組類別。A model is a set of classes that represent the data that the app manages. 此應用程式的模型是單一 TodoItem 類別。The model for this app is a single TodoItem class.

  • 在 [方案總管] 中,以滑鼠右鍵按一下專案。In Solution Explorer, right-click the project. 選取 [新增] > [新增資料夾]。Select Add > New Folder. 將資料夾命名為 ModelsName the folder Models.

  • 以滑鼠右鍵按一下 Models 資料夾,然後選取 [新增] > [類別]。Right-click the Models folder and select Add > Class. 將類別命名為 TodoItem,然後選取 [新增]。Name the class TodoItem and select Add.

  • 使用下列程式碼取代範本程式碼:Replace the template code with the following code:

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

Id 屬性的功能相當於關聯式資料庫中的唯一索引鍵。The Id property functions as the unique key in a relational database.

模型類別可位於專案中的任何位置,但依照慣例會使用 Models 資料夾。Model classes can go anywhere in the project, but the Models folder is used by convention.

新增資料庫內容Add a database context

「資料庫內容」是為資料模型協調 Entity Framework 功能的主要類別。The database context is the main class that coordinates Entity Framework functionality for a data model. 此類別是透過衍生自 Microsoft.EntityFrameworkCore.DbContext 類別來建立。This class is created by deriving from the Microsoft.EntityFrameworkCore.DbContext class.

新增 Microsoft.EntityFrameworkCore.SqlServerAdd Microsoft.EntityFrameworkCore.SqlServer

  • 在 [工具] 功能表上,選取 [NuGet 套件管理員] > [管理解決方案的 NuGet 套件]。From the Tools menu, select NuGet Package Manager > Manage NuGet Packages for Solution.
  • 選取 [瀏覽] 索引標籤,然後在搜尋方塊中輸入 Microsoft.EntityFrameworkCore.SqlServerSelect the Browse tab, and then enter Microsoft.EntityFrameworkCore.SqlServer in the search box.
  • 在左窗格中選取 [ microsoft.entityframeworkcore ]。Select Microsoft.EntityFrameworkCore.SqlServer in the left pane.
  • 選取右窗格中的 [專案] 核取方塊,然後選取 [安裝]。Select the Project check box in the right pane and then select Install.
  • 使用上述指示來新增 Microsoft.EntityFrameworkCore.InMemory NuGet 套件。Use the preceding instructions to add the Microsoft.EntityFrameworkCore.InMemory NuGet package.

NuGet 封裝管理員

新增 TodoCoNtext 資料庫內容Add the TodoContext database context

  • 以滑鼠右鍵按一下 Models 資料夾,然後選取 [新增] > [類別]。Right-click the Models folder and select Add > Class. 將類別命名為 TodoContext,然後按一下 [新增]。Name the class TodoContext and click Add.
  • 輸入下列程式碼:Enter the following code:

    using Microsoft.EntityFrameworkCore;
    
    namespace TodoApi.Models
    {
        public class TodoContext : DbContext
        {
            public TodoContext(DbContextOptions<TodoContext> options)
                : base(options)
            {
            }
    
            public DbSet<TodoItem> TodoItems { get; set; }
        }
    }
    

登錄資料庫內容Register the database context

在 ASP.NET Core 中,資料庫內容等服務必須向相依性插入 (DI) 容器註冊。In ASP.NET Core, services such as the DB context must be registered with the dependency injection (DI) container. 此容器會將服務提供給控制器。The container provides the service to controllers.

使用下列醒目提示的程式碼更新 Startup.csUpdate Startup.cs with the following highlighted code:

// Unused usings removed
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.EntityFrameworkCore;
using TodoApi.Models;

namespace TodoApi
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<TodoContext>(opt =>
               opt.UseInMemoryDatabase("TodoList"));
            services.AddControllers();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}

上述程式碼:The preceding code:

  • 移除未使用的 using 宣告。Removes unused using declarations.
  • 將資料庫內容新增至 DI 容器。Adds the database context to the DI container.
  • 指定資料庫內容將會使用記憶體內部資料庫。Specifies that the database context will use an in-memory database.

Scaffold 控制器Scaffold a controller

  • 以滑鼠右鍵按一下 Controllers 資料夾。Right-click the Controllers folder.

  • 選取 [加入>新增 scaffold 專案]。Select Add > New Scaffolded Item.

  • 選取 [使用 Entity Framework 執行動作的 API 控制器],然後選取 [新增]。Select API Controller with actions, using Entity Framework, and then select Add.

  • 在 [使用 Entity Framework 執行動作的 API 控制器] 對話方塊中:In the Add API Controller with actions, using Entity Framework dialog:

    • 模型類別中選取 [ TodoItem (TodoApi) ]。Select TodoItem (TodoApi.Models) in the Model class.
    • 選取資料內容類別中的 [ TodoCoNtext (TodoApi) ]。Select TodoContext (TodoApi.Models) in the Data context class.
    • 選取 [新增]。Select Add.

產生的程式碼:The generated code:

  • [ApiController]屬性標記類別。Marks the class with the [ApiController] attribute. 這個屬性表示控制器會回應 Web API 要求。This attribute indicates that the controller responds to web API requests. 如需屬性所啟用之特定行為的相關資訊,請參閱 使用 ASP.NET Core 建立 Web APIFor information about specific behaviors that the attribute enables, see 使用 ASP.NET Core 建立 Web API.
  • 使用 DI 將資料庫內容 (TodoContext) 插入到控制器中。Uses DI to inject the database context (TodoContext) into the controller. 控制器中的每一個 CRUD 方法都會使用資料庫內容。The database context is used in each of the CRUD methods in the controller.

檢查 PostTodoItem 建立方法Examine the PostTodoItem create method

取代 PostTodoItem 中的 return 陳述式,以使用 nameof 運算子:Replace the return statement in the PostTodoItem to use the nameof operator:

// POST: api/TodoItems
[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]屬性所示。The preceding code is an HTTP POST method, as indicated by the [HttpPost] attribute. 該方法會從 HTTP 要求本文取得待辦事項的值。The method gets the value of the to-do item from the body of the HTTP request.

CreatedAtAction 方法:The CreatedAtAction method:

  • 成功時會傳回 HTTP 201 狀態碼。Returns an HTTP 201 status code if successful. 對於可在伺服器上建立新資源的 HTTP POST 方法,其標準回應是 HTTP 201。HTTP 201 is the standard response for an HTTP POST method that creates a new resource on the server.
  • Location標頭新增到回應。Adds a Location header to the response. Location 標頭會指定新建待辦事項的 URIThe Location header specifies the URI of the newly created to-do item. 如需詳細資訊,請參閱 10.2.2 201 Created (已建立 10.2.2 201)。For more information, see 10.2.2 201 Created.
  • 參考 GetTodoItem 動作以建立 Location 標頭的 URI。References the GetTodoItem action to create the Location header's URI. C# nameof 關鍵字是用來避免在 CreatedAtAction 呼叫中以硬式編碼方式寫入動作名稱。The C# nameof keyword is used to avoid hard-coding the action name in the CreatedAtAction call.

安裝 PostmanInstall Postman

本教學課程使用 Postman 來測試 Web API。This tutorial uses Postman to test the web API.

  • 安裝 PostmanInstall Postman
  • 啟動 Web 應用程式。Start the web app.
  • 啟動 Postman。Start Postman.
  • 停用 [SSL certificate verification] (SSL 憑證驗證)Disable SSL certificate verification
    • 從 [檔案 > 設定] ( [一般] 索引標籤),停用SSL 憑證驗證From File > Settings (General tab), disable SSL certificate verification.

      警告

      在測試控制器之後,請重新啟用 [SSL certificate verification] (SSL 憑證驗證)。Re-enable SSL certificate verification after testing the controller.

使用 Postman 測試 PostTodoItemTest PostTodoItem with Postman

  • 建立新的要求。Create a new request.

  • 將 HTTP 方法設為 POSTSet the HTTP method to POST.

  • 選取 [本文] 索引標籤。Select the Body tab.

  • 選取 [原始] 選項按鈕。Select the raw radio button.

  • 將類型設定為 JSON (application/json)Set the type to JSON (application/json).

  • 在要求本文中,針對待辦項目輸入 JSON:In the request body enter JSON for a to-do item:

    {
      "name":"walk dog",
      "isComplete":true
    }
    
  • 選取 [傳送]。Select Send.

    Postman 與建立要求

測試位置標頭 URITest the location header URI

  • 在 [回應] 窗格中選取 [標頭] 索引標籤。Select the Headers tab in the Response pane.

  • 複製 [位置] 標頭值:Copy the Location header value:

    Postman 主控台的 [標頭] 索引標籤

  • 將方法設定為 GET。Set the method to GET.

  • 貼上 URI (例如 https://localhost:5001/api/TodoItems/1)。Paste the URI (for example, https://localhost:5001/api/TodoItems/1).

  • 選取 [傳送]。Select Send.

檢查 GET 方法Examine the GET methods

這些方法會實作兩個 GET 端點:These methods implement two GET endpoints:

  • GET /api/TodoItems
  • GET /api/TodoItems/{id}

從瀏覽器或 Postman 呼叫這兩個端點來測試應用程式。Test the app by calling the two endpoints from a browser or Postman. 例如:For example:

GetTodoItems 的呼叫會產生類似下列的回應:A response similar to the following is produced by the call to GetTodoItems:

[
  {
    "id": 1,
    "name": "Item1",
    "isComplete": false
  }
]

使用 Postman 測試 GetTest Get with Postman

  • 建立新的要求。Create a new request.
  • 將 HTTP 方法設定為 GETSet the HTTP method to GET.
  • 將要求 URL 設定為 https://localhost:<port>/api/TodoItemsSet the request URL to https://localhost:<port>/api/TodoItems. 例如,https://localhost:5001/api/TodoItemsFor example, https://localhost:5001/api/TodoItems.
  • 在 Postman 中,設定 [Two pane view] (雙窗格檢視)。Set Two pane view in Postman.
  • 選取 [傳送]。Select Send.

這個應用程式會使用記憶體內部資料庫。This app uses an in-memory database. 如果應用程式在停止後再啟動,上述 GET 要求將不會傳回任何資料。If the app is stopped and started, the preceding GET request will not return any data. 如果沒有傳回任何資料,請將資料 POST 到應用程式。If no data is returned, POST data to the app.

傳送和 URL 路徑Routing and URL paths

[HttpGet] 屬性代表回應 HTTP GET 要求的方法。The [HttpGet] attribute denotes a method that responds to an HTTP GET request. 每個方法的 URL 路徑的建構方式如下:The URL path for each method is constructed as follows:

  • 一開始在控制器的 Route 屬性中使用範本字串:Start with the template string in the controller's Route attribute:

    [Route("api/[controller]")]
    [ApiController]
    public class TodoItemsController : ControllerBase
    {
        private readonly TodoContext _context;
    
        public TodoItemsController(TodoContext context)
        {
            _context = context;
        }
    
  • 以控制器的名稱取代 [controller],也就是將控制器類別名稱減去 "Controller" 字尾。Replace [controller] with the name of the controller, which by convention is the controller class name minus the "Controller" suffix. 在此範例中,控制器類別名稱是 TodoItemsController,因此控制器名稱是 "TodoItems"。For this sample, the controller class name is TodoItemsController, so the controller name is "TodoItems". ASP.NET Core 路由不區分大小寫。ASP.NET Core routing is case insensitive.

  • 如果 [HttpGet] 屬性具有路由範本 (例如 [HttpGet("products")]),請將其附加到路徑。If the [HttpGet] attribute has a route template (for example, [HttpGet("products")]), append that to the path. 此範例不使用範本。This sample doesn't use a template. 如需詳細資訊,請參閱使用 Http[Verb] 屬性的屬性路由For more information, see Attribute routing with Http[Verb] attributes.

在下列 GetTodoItem 方法中,"{id}" 是待辦事項唯一識別碼的預留位置變數。In the following GetTodoItem method, "{id}" is a placeholder variable for the unique identifier of the to-do item. 叫用 GetTodoItem 時,URL 中 "{id}" 的值會在其 id 參數中提供給方法。When GetTodoItem is invoked, the value of "{id}" in the URL is provided to the method in its id parameter.

// GET: api/TodoItems/5
[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> 類型The return type of the GetTodoItems and GetTodoItem methods is ActionResult<T> type. ASP.NET Core 會自動將物件序列化為 JSON,並將 JSON 寫入至回應訊息的本文。ASP.NET Core automatically serializes the object to JSON and writes the JSON into the body of the response message. 此傳回型別的回應碼為 200,假設沒有任何未處理的例外狀況。The response code for this return type is 200, assuming there are no unhandled exceptions. 未處理的例外狀況會轉譯成 5xx 錯誤。Unhandled exceptions are translated into 5xx errors.

ActionResult 傳回型別可代表各種 HTTP 狀態碼。ActionResult return types can represent a wide range of HTTP status codes. 例如,GetTodoItem 可傳回兩個不同的狀態值:For example, GetTodoItem can return two different status values:

  • 如果沒有項目符合所要求的識別碼,方法會傳回 404 NotFound 錯誤碼。If no item matches the requested ID, the method returns a 404 NotFound error code.
  • 否則,方法會傳回 200 與 JSON 回應本文。Otherwise, the method returns 200 with a JSON response body. 傳回 item 會導致 HTTP 200 回應。Returning item results in an HTTP 200 response.

PutTodoItem 方法The PutTodoItem method

檢查 PutTodoItem 方法:Examine the PutTodoItem method:

// PUT: api/TodoItems/5
[HttpPut("{id}")]
public async Task<IActionResult> PutTodoItem(long id, TodoItem todoItem)
{
    if (id != todoItem.Id)
    {
        return BadRequest();
    }

    _context.Entry(todoItem).State = EntityState.Modified;

    try
    {
        await _context.SaveChangesAsync();
    }
    catch (DbUpdateConcurrencyException)
    {
        if (!TodoItemExists(id))
        {
            return NotFound();
        }
        else
        {
            throw;
        }
    }

    return NoContent();
}

PutTodoItem 類似於 PostTodoItem,但是會使用 HTTP PUT。PutTodoItem is similar to PostTodoItem, except it uses HTTP PUT. 回應是 204 (No Content) (204 (沒有內容))。The response is 204 (No Content). 根據 HTTP 規格,PUT 要求需要用戶端傳送整個更新的實體,而不只是變更。According to the HTTP specification, a PUT request requires the client to send the entire updated entity, not just the changes. 若要支援部分更新,請使用 HTTP PATCHTo support partial updates, use HTTP PATCH.

如果在呼叫 PutTodoItem 時發生錯誤,請呼叫 GET 以確保資料庫中有項目。If you get an error calling PutTodoItem, call GET to ensure there's an item in the database.

測試 PutTodoItem 方法Test the PutTodoItem method

這個範例會使用必須在每次啟動應用程式時初始化的記憶體內部資料庫。This sample uses an in-memory database that must be initialized each time the app is started. 資料庫中必須有項目,您才能進行 PUT 呼叫。There must be an item in the database before you make a PUT call. 在發出 PUT 呼叫之前,請先呼叫 GET 以確保資料庫中有項目。Call GET to insure there's an item in the database before making a PUT call.

更新識別碼為 1 的待辦事項,並將其名稱設定為 "feed fish":Update the to-do item that has ID = 1 and set its name to "feed fish":

  {
    "ID":1,
    "name":"feed fish",
    "isComplete":true
  }

下圖顯示 Postman 更新:The following image shows the Postman update:

顯示 204 (沒有內容) 回應的 Postman 主控台

DeleteTodoItem 方法The DeleteTodoItem method

檢查 DeleteTodoItem 方法:Examine the DeleteTodoItem method:

// DELETE: api/TodoItems/5
[HttpDelete("{id}")]
public async Task<ActionResult<TodoItem>> DeleteTodoItem(long id)
{
    var todoItem = await _context.TodoItems.FindAsync(id);
    if (todoItem == null)
    {
        return NotFound();
    }

    _context.TodoItems.Remove(todoItem);
    await _context.SaveChangesAsync();

    return todoItem;
}

測試 DeleteTodoItem 方法Test the DeleteTodoItem method

使用 Postman 刪除待辦事項:Use Postman to delete a to-do item:

  • 將方法設定為 DELETESet the method to DELETE.
  • 設定要刪除之物件的 URI (例如 https://localhost:5001/api/TodoItems/1)。Set the URI of the object to delete (for example https://localhost:5001/api/TodoItems/1).
  • 選取 [傳送]。Select Send.

使用 JavaScript 呼叫 Web APICall the web API with JavaScript

請參閱教學課程:使用 JavaScript 呼叫 ASP.NET Core Web APISee Tutorial: Call an ASP.NET Core web API with JavaScript.

在本教學課程中,您將了解如何:In this tutorial, you learn how to:

  • 建立 Web API 專案。Create a web API project.
  • 新增模型類別和資料庫內容。Add a model class and a database context.
  • 新增控制器。Add a controller.
  • 新增 CRUD 方法。Add CRUD methods.
  • 設定路由和 URL 路徑。Configure routing and URL paths.
  • 指定傳回值。Specify return values.
  • 使用 Postman 呼叫 Web API。Call the web API with Postman.
  • 使用 JavaScript 呼叫 Web API。Call the web API with JavaScript.

結束時,您將會有一個可管理關聯式資料庫中所儲存「待辦事項」的 Web API。At the end, you have a web API that can manage "to-do" items stored in a relational database.

概觀Overview

本教學課程會建立以下 API:This tutorial creates the following API:

APIAPI 描述Description 要求本文Request body 回應本文Response body
GET /api/TodoItemsGET /api/TodoItems 取得所有待辦事項Get all to-do items NoneNone 待辦事項的陣列Array of to-do items
GET /api/TodoItems/{識別碼}GET /api/TodoItems/{id} 依識別碼取得項目Get an item by ID NoneNone 待辦事項To-do item
POST /api/TodoItemsPOST /api/TodoItems 新增記錄Add a new item 待辦事項To-do item 待辦事項To-do item
PUT /api/TodoItems/{識別碼}PUT /api/TodoItems/{id} 更新現有的項目  Update an existing item   待辦事項To-do item NoneNone
刪除/api/TodoItems/{id}    DELETE /api/TodoItems/{id}         刪除專案Delete an item     NoneNone NoneNone

下圖顯示應用程式的設計。The following diagram shows the design of the app.

左側方塊代表用戶端。

必要條件:Prerequisites

警告

如果您使用 Visual Studio 2017,請參閱 dotnet/sdk 問題 #3124 (英文),以取得未使用 Visual Studio 的 .NET Core SDK 版本相關資訊。If you use Visual Studio 2017, see dotnet/sdk issue #3124 for information about .NET Core SDK versions that don't work with Visual Studio.

建立 Web 專案Create a web project

  • 從 [檔案] 功能表中,選取 [新增>專案]。From the File menu, select New > Project.
  • 選取 ASP.NET Core Web 應用程式範本,然後按一下 [下一步]。Select the ASP.NET Core Web Application template and click Next.
  • 將專案命名為 TodoApi,然後按一下 [建立]。Name the project TodoApi and click Create.
  • 在 [建立新的 ASP.NET Core Web 應用程式] 對話方塊中,確認選取 [.NET Core] 和 [ASP.NET Core 2.2]。In the Create a new ASP.NET Core Web Application dialog, confirm that .NET Core and ASP.NET Core 2.2 are selected. 選取 API 範本,然後按一下 [建立]。Select the API template and click Create. 選取 [Enable Docker Support] (啟用 Docker 支援)。Don't select Enable Docker Support.

VS 新增專案對話方塊

測試 APITest the API

專案範本會建立 values API。The project template creates a values API. 從瀏覽器呼叫 Get 方法來測試應用程式。Call the Get method from a browser to test the app.

按 Ctrl+F5 執行應用程式。Press Ctrl+F5 to run the app. Visual Studio 會啟動瀏覽器並巡覽至 https://localhost:<port>/api/values,其中 <port> 是隨機選擇的通訊埠編號。Visual Studio launches a browser and navigates to https://localhost:<port>/api/values, where <port> is a randomly chosen port number.

如果出現對話方塊詢問您是否應該信任 IIS Express 憑證,請選取 [是]。If you get a dialog box that asks if you should trust the IIS Express certificate, select Yes. 在接著出現的 [安全性警告] 對話方塊中,選取 [是]。In the Security Warning dialog that appears next, select Yes.

即會傳回下列 JSON:The following JSON is returned:

["value1","value2"]

新增模型類別Add a model class

「模型」是代表應用程式所管理資料的一組類別。A model is a set of classes that represent the data that the app manages. 此應用程式的模型是單一 TodoItem 類別。The model for this app is a single TodoItem class.

  • 在 [方案總管] 中,以滑鼠右鍵按一下專案。In Solution Explorer, right-click the project. 選取 [新增] > [新增資料夾]。Select Add > New Folder. 將資料夾命名為 ModelsName the folder Models.

  • 以滑鼠右鍵按一下 Models 資料夾,然後選取 [新增] > [類別]。Right-click the Models folder and select Add > Class. 將類別命名為 TodoItem,然後選取 [新增]。Name the class TodoItem and select Add.

  • 使用下列程式碼取代範本程式碼:Replace the template code with the following code:

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

Id 屬性的功能相當於關聯式資料庫中的唯一索引鍵。The Id property functions as the unique key in a relational database.

模型類別可位於專案中的任何位置,但依照慣例會使用 Models 資料夾。Model classes can go anywhere in the project, but the Models folder is used by convention.

新增資料庫內容Add a database context

「資料庫內容」是為資料模型協調 Entity Framework 功能的主要類別。The database context is the main class that coordinates Entity Framework functionality for a data model. 此類別是透過衍生自 Microsoft.EntityFrameworkCore.DbContext 類別來建立。This class is created by deriving from the Microsoft.EntityFrameworkCore.DbContext class.

  • 以滑鼠右鍵按一下 Models 資料夾,然後選取 [新增] > [類別]。Right-click the Models folder and select Add > Class. 將類別命名為 TodoContext,然後按一下 [新增]。Name the class TodoContext and click Add.
  • 使用下列程式碼取代範本程式碼:Replace the template code with the following code:

    using Microsoft.EntityFrameworkCore;
    
    namespace TodoApi.Models
    {
        public class TodoContext : DbContext
        {
            public TodoContext(DbContextOptions<TodoContext> options)
                : base(options)
            {
            }
    
            public DbSet<TodoItem> TodoItems { get; set; }
        }
    }
    

登錄資料庫內容Register the database context

在 ASP.NET Core 中,資料庫內容等服務必須向相依性插入 (DI) 容器註冊。In ASP.NET Core, services such as the DB context must be registered with the dependency injection (DI) container. 此容器會將服務提供給控制器。The container provides the service to controllers.

使用下列醒目提示的程式碼更新 Startup.csUpdate Startup.cs with the following highlighted code:

// Unused usings removed
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using TodoApi.Models;

namespace TodoApi
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the 
        //container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<TodoContext>(opt =>
                opt.UseInMemoryDatabase("TodoList"));
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        }

        // This method gets called by the runtime. Use this method to configure the HTTP 
        //request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                // The default HSTS value is 30 days. You may want to change this for 
                // production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseMvc();
        }
    }
}

上述程式碼:The preceding code:

  • 移除未使用的 using 宣告。Removes unused using declarations.
  • 將資料庫內容新增至 DI 容器。Adds the database context to the DI container.
  • 指定資料庫內容將會使用記憶體內部資料庫。Specifies that the database context will use an in-memory database.

新增控制器Add a controller

  • 以滑鼠右鍵按一下 Controllers 資料夾。Right-click the Controllers folder.

  • 選取 [ 新增 > 新專案]。Select Add > New Item.

  • 在 [新增項目] 對話方塊中,選取 [API 控制器類別] 範本。In the Add New Item dialog, select the API Controller Class template.

  • 將類別命名為 TodoController,然後選取 [新增]。Name the class TodoController, and select Add.

    在搜尋方塊中輸入 controller 且已選取 Web API 控制器的 [新增項目] 對話方塊

  • 使用下列程式碼取代範本程式碼:Replace the template code with the following code:

    using Microsoft.AspNetCore.Mvc;
    using Microsoft.EntityFrameworkCore;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using TodoApi.Models;
    
    namespace TodoApi.Controllers
    {
        [Route("api/[controller]")]
        [ApiController]
        public class TodoController : ControllerBase
        {
            private readonly TodoContext _context;
    
            public TodoController(TodoContext context)
            {
                _context = context;
    
                if (_context.TodoItems.Count() == 0)
                {
                    // Create a new TodoItem if collection is empty,
                    // which means you can't delete all TodoItems.
                    _context.TodoItems.Add(new TodoItem { Name = "Item1" });
                    _context.SaveChanges();
                }
            }
        }
    }
    

上述程式碼:The preceding code:

  • 定義不含方法的 API 控制器類別。Defines an API controller class without methods.
  • [ApiController]屬性標記類別。Marks the class with the [ApiController] attribute. 這個屬性表示控制器會回應 Web API 要求。This attribute indicates that the controller responds to web API requests. 如需屬性所啟用之特定行為的相關資訊,請參閱 使用 ASP.NET Core 建立 Web APIFor information about specific behaviors that the attribute enables, see 使用 ASP.NET Core 建立 Web API.
  • 使用 DI 將資料庫內容 (TodoContext) 插入到控制器中。Uses DI to inject the database context (TodoContext) into the controller. 控制器中的每一個 CRUD 方法都會使用資料庫內容。The database context is used in each of the CRUD methods in the controller.
  • 如果資料庫是空的,請將名為 Item1 的項目新增至資料庫。Adds an item named Item1 to the database if the database is empty. 此程式碼是在建構函式中,因此每次執行都會有新的 HTTP 要求。This code is in the constructor, so it runs every time there's a new HTTP request. 如果您刪除所有項目,則建構函式會在下次呼叫 API 方法時重新建立 Item1If you delete all items, the constructor creates Item1 again the next time an API method is called. 因此看起來雖然像是刪除失敗,但實際為成功。So it may look like the deletion didn't work when it actually did work.

新增 Get 方法Add Get methods

若要提供擷取待辦事項的 API,請在 TodoController 類別中新增下列方法:To provide an API that retrieves to-do items, add the following methods to the TodoController class:

// GET: api/Todo
[HttpGet]
public async Task<ActionResult<IEnumerable<TodoItem>>> GetTodoItems()
{
    return await _context.TodoItems.ToListAsync();
}

// GET: api/Todo/5
[HttpGet("{id}")]
public async Task<ActionResult<TodoItem>> GetTodoItem(long id)
{
    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        return NotFound();
    }

    return todoItem;
}

這些方法會實作兩個 GET 端點:These methods implement two GET endpoints:

  • GET /api/todo
  • GET /api/todo/{id}

如果應用程式仍在執行,請將其停止。Stop the app if it's still running. 然後重新予以執行以包含最新的變更。Then run it again to include the latest changes.

從瀏覽器呼叫這兩個端點來測試應用程式。Test the app by calling the two endpoints from a browser. 例如:For example:

  • https://localhost:<port>/api/todo
  • https://localhost:<port>/api/todo/1

以下是呼叫 GetTodoItems 所產生的 HTTP 回應:The following HTTP response is produced by the call to GetTodoItems:

[
  {
    "id": 1,
    "name": "Item1",
    "isComplete": false
  }
]

傳送和 URL 路徑Routing and URL paths

[HttpGet] 屬性代表回應 HTTP GET 要求的方法。The [HttpGet] attribute denotes a method that responds to an HTTP GET request. 每個方法的 URL 路徑的建構方式如下:The URL path for each method is constructed as follows:

  • 一開始在控制器的 Route 屬性中使用範本字串:Start with the template string in the controller's Route attribute:

    namespace TodoApi.Controllers
    {
        [Route("api/[controller]")]
        [ApiController]
        public class TodoController : ControllerBase
        {
            private readonly TodoContext _context;
    
  • 以控制器的名稱取代 [controller],也就是將控制器類別名稱減去 "Controller" 字尾。Replace [controller] with the name of the controller, which by convention is the controller class name minus the "Controller" suffix. 在此範例中,控制器類別名稱是 TodoController,因此容器名稱是 "todo"。For this sample, the controller class name is TodoController, so the controller name is "todo". ASP.NET Core 路由不區分大小寫。ASP.NET Core routing is case insensitive.

  • 如果 [HttpGet] 屬性具有路由範本 (例如 [HttpGet("products")]),請將其附加到路徑。If the [HttpGet] attribute has a route template (for example, [HttpGet("products")]), append that to the path. 此範例不使用範本。This sample doesn't use a template. 如需詳細資訊,請參閱使用 Http[Verb] 屬性的屬性路由For more information, see Attribute routing with Http[Verb] attributes.

在下列 GetTodoItem 方法中,"{id}" 是待辦事項唯一識別碼的預留位置變數。In the following GetTodoItem method, "{id}" is a placeholder variable for the unique identifier of the to-do item. 在叫用 GetTodoItem 時,會將 URL 中的 "{id}" 值提供給方法的 id 參數。When GetTodoItem is invoked, the value of "{id}" in the URL is provided to the method in itsid parameter.

// GET: api/Todo/5
[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> 類型The return type of the GetTodoItems and GetTodoItem methods is ActionResult<T> type. ASP.NET Core 會自動將物件序列化為 JSON,並將 JSON 寫入至回應訊息的本文。ASP.NET Core automatically serializes the object to JSON and writes the JSON into the body of the response message. 此傳回型別的回應碼為 200,假設沒有任何未處理的例外狀況。The response code for this return type is 200, assuming there are no unhandled exceptions. 未處理的例外狀況會轉譯成 5xx 錯誤。Unhandled exceptions are translated into 5xx errors.

ActionResult 傳回型別可代表各種 HTTP 狀態碼。ActionResult return types can represent a wide range of HTTP status codes. 例如,GetTodoItem 可傳回兩個不同的狀態值:For example, GetTodoItem can return two different status values:

  • 如果沒有項目符合所要求的識別碼,方法會傳回 404 NotFound 錯誤碼。If no item matches the requested ID, the method returns a 404 NotFound error code.
  • 否則,方法會傳回 200 與 JSON 回應本文。Otherwise, the method returns 200 with a JSON response body. 傳回 item 會導致 HTTP 200 回應。Returning item results in an HTTP 200 response.

測試 GetTodoItems 方法Test the GetTodoItems method

本教學課程使用 Postman 來測試 Web API。This tutorial uses Postman to test the web API.

  • 安裝PostmanInstall Postman.
  • 啟動 Web 應用程式。Start the web app.
  • 啟動 Postman。Start Postman.
  • 停用SSL 憑證驗證Disable SSL certificate verification.
  • 從 [檔案 > 設定] ( [一般] 索引標籤),停用SSL 憑證驗證From File > Settings (General tab), disable SSL certificate verification.

警告

在測試控制器之後,請重新啟用 [SSL certificate verification] (SSL 憑證驗證)。Re-enable SSL certificate verification after testing the controller.

  • 建立新的要求。Create a new request.
    • 將 HTTP 方法設定為 GETSet the HTTP method to GET.
    • 將要求 URL 設定為 https://localhost:<port>/api/todoSet the request URL to https://localhost:<port>/api/todo. 例如,https://localhost:5001/api/todoFor example, https://localhost:5001/api/todo.
  • 在 Postman 中,設定 [Two pane view] (雙窗格檢視)。Set Two pane view in Postman.
  • 選取 [傳送]。Select Send.

Postman 與 GET 要求

新增 Create 方法Add a Create method

Controllers/TodoController.cs 內部新增下列 PostTodoItem 方法:Add the following PostTodoItem method inside of Controllers/TodoController.cs:

// POST: api/Todo
[HttpPost]
public async Task<ActionResult<TodoItem>> PostTodoItem(TodoItem item)
{
    _context.TodoItems.Add(item);
    await _context.SaveChangesAsync();

    return CreatedAtAction(nameof(GetTodoItem), new { id = item.Id }, item);
}

上述程式碼是 HTTP POST 方法,如[HttpPost]屬性所示。The preceding code is an HTTP POST method, as indicated by the [HttpPost] attribute. 該方法會從 HTTP 要求本文取得待辦事項的值。The method gets the value of the to-do item from the body of the HTTP request.

CreatedAtAction 方法:The CreatedAtAction method:

  • 成功時會傳回 HTTP 201 狀態碼。Returns an HTTP 201 status code, if successful. 對於可在伺服器上建立新資源的 HTTP POST 方法,其標準回應是 HTTP 201。HTTP 201 is the standard response for an HTTP POST method that creates a new resource on the server.

  • Location 標頭加到回應中。Adds a Location header to the response. Location 標頭指定新建立之待辦事項的 URI。The Location header specifies the URI of the newly created to-do item. 如需詳細資訊,請參閱 10.2.2 201 Created (已建立 10.2.2 201)。For more information, see 10.2.2 201 Created.

  • 參考 GetTodoItem 動作以建立 Location 標頭的 URI。References the GetTodoItem action to create the Location header's URI. C# nameof 關鍵字是用來避免在 CreatedAtAction 呼叫中以硬式編碼方式寫入動作名稱。The C# nameof keyword is used to avoid hard-coding the action name in the CreatedAtAction call.

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

測試 PostTodoItem 方法Test the PostTodoItem method

  • 建置專案。Build the project.

  • 在 Postman 中,將 HTTP 方法設定為 POSTIn Postman, set the HTTP method to POST.

  • 選取 [本文] 索引標籤。Select the Body tab.

  • 選取 [原始] 選項按鈕。Select the raw radio button.

  • 將類型設定為 JSON (application/json)Set the type to JSON (application/json).

  • 在要求本文中,針對待辦項目輸入 JSON:In the request body enter JSON for a to-do item:

    {
      "name":"walk dog",
      "isComplete":true
    }
    
  • 選取 [傳送]。Select Send.

    Postman 與建立要求

    如果您收到 405「不允許的方法」錯誤,可能是由於新增 PostTodoItem 方法之後未編譯專案所導致。If you get a 405 Method Not Allowed error, it's probably the result of not compiling the project after adding the PostTodoItem method.

測試位置標頭 URITest the location header URI

  • 在 [回應] 窗格中選取 [標頭] 索引標籤。Select the Headers tab in the Response pane.

  • 複製 [位置] 標頭值:Copy the Location header value:

    Postman 主控台的 [標頭] 索引標籤

  • 將方法設定為 GET。Set the method to GET.

  • 貼上 URI (例如 https://localhost:5001/api/Todo/2)。Paste the URI (for example, https://localhost:5001/api/Todo/2).

  • 選取 [傳送]。Select Send.

新增 PutTodoItem 方法Add a PutTodoItem method

新增以下 PutTodoItem 方法:Add the following PutTodoItem method:

// PUT: api/Todo/5
[HttpPut("{id}")]
public async Task<IActionResult> PutTodoItem(long id, TodoItem item)
{
    if (id != item.Id)
    {
        return BadRequest();
    }

    _context.Entry(item).State = EntityState.Modified;
    await _context.SaveChangesAsync();

    return NoContent();
}

PutTodoItem 類似於 PostTodoItem,但是會使用 HTTP PUT。PutTodoItem is similar to PostTodoItem, except it uses HTTP PUT. 回應是 204 (No Content) (204 (沒有內容))。The response is 204 (No Content). 根據 HTTP 規格,PUT 要求需要用戶端傳送整個更新的實體,而不只是變更。According to the HTTP specification, a PUT request requires the client to send the entire updated entity, not just the changes. 若要支援部分更新,請使用 HTTP PATCHTo support partial updates, use HTTP PATCH.

如果在呼叫 PutTodoItem 時發生錯誤,請呼叫 GET 以確保資料庫中有項目。If you get an error calling PutTodoItem, call GET to ensure there's an item in the database.

測試 PutTodoItem 方法Test the PutTodoItem method

這個範例會使用必須在每次啟動應用程式時初始化的記憶體內部資料庫。This sample uses an in-memory database that must be initialized each time the app is started. 資料庫中必須有項目,您才能進行 PUT 呼叫。There must be an item in the database before you make a PUT call. 在發出 PUT 呼叫之前,請先呼叫 GET 以確保資料庫中有項目。Call GET to insure there's an item in the database before making a PUT call.

更新識別碼為 1 的待辦事項,並將其名稱設定為 "feed fish":Update the to-do item that has id = 1 and set its name to "feed fish":

  {
    "ID":1,
    "name":"feed fish",
    "isComplete":true
  }

下圖顯示 Postman 更新:The following image shows the Postman update:

顯示 204 (沒有內容) 回應的 Postman 主控台

新增 DeleteTodoItem 方法Add a DeleteTodoItem method

新增以下 DeleteTodoItem 方法:Add the following DeleteTodoItem method:

// DELETE: api/Todo/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();
}

DeleteTodoItem 回應是 204 (No Content) (204 (沒有內容))。The DeleteTodoItem response is 204 (No Content).

測試 DeleteTodoItem 方法Test the DeleteTodoItem method

使用 Postman 刪除待辦事項:Use Postman to delete a to-do item:

  • 將方法設定為 DELETESet the method to DELETE.
  • 設定要刪除之物件的 URI (例如 https://localhost:5001/api/todo/1)。Set the URI of the object to delete (for example https://localhost:5001/api/todo/1).
  • 選取 [傳送]。Select Send.

範例應用程式可讓您刪除所有項目。The sample app allows you to delete all the items. 但刪除最後一個項目之後,模型類別建構函式會在下次呼叫 API 時建立新的項目。However, when the last item is deleted, a new one is created by the model class constructor the next time the API is called.

使用 JavaScript 呼叫 Web APICall the web API with JavaScript

在此節中,將會新增 HTML 網頁,以使用 JavaScript 來呼叫 Web API。In this section, an HTML page is added that uses JavaScript to call the web API. jQuery 會起始要求。jQuery initiates the request. JavaScript 會使用來自 Web API 回應的詳細資料來更新頁面。JavaScript updates the page with the details from the web API's response.

藉由使用下列反白顯示的程式碼更新 Startup.cs,來設定應用程式提供靜態檔案啟用預設檔案對應Configure the app to serve static files and enable default file mapping by updating Startup.cs with the following highlighted code:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        // The default HSTS value is 30 days. You may want to change this for 
        // production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }

    app.UseDefaultFiles();
    app.UseStaticFiles();
    app.UseHttpsRedirection();
    app.UseMvc();
}

在專案目錄中建立 wwwroot 資料夾。Create a wwwroot folder in the project directory.

將名為 index.html 的 HTML 檔案新增至 wwwroot 目錄。Add an HTML file named index.html to the wwwroot directory. 將其內容取代為下列標記:Replace its contents with the following markup:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>To-do CRUD</title>
    <style>
        input[type='submit'], button, [aria-label] {
            cursor: pointer;
        }

        #spoiler {
            display: none;
        }

        table {
            font-family: Arial, sans-serif;
            border: 1px solid;
            border-collapse: collapse;
        }

        th {
            background-color: #0066CC;
            color: white;
        }

        td {
            border: 1px solid;
            padding: 5px;
        }
    </style>
</head>
<body>
    <h1>To-do CRUD</h1>
    <h3>Add</h3>
    <form action="javascript:void(0);" method="POST" onsubmit="addItem()">
        <input type="text" id="add-name" placeholder="New to-do">
        <input type="submit" value="Add">
    </form>

    <div id="spoiler">
        <h3>Edit</h3>
        <form class="my-form">
            <input type="hidden" id="edit-id">
            <input type="checkbox" id="edit-isComplete">
            <input type="text" id="edit-name">
            <input type="submit" value="Save">
            <a onclick="closeInput()" aria-label="Close">&#10006;</a>
        </form>
    </div>

    <p id="counter"></p>

    <table>
        <tr>
            <th>Is Complete</th>
            <th>Name</th>
            <th></th>
            <th></th>
        </tr>
        <tbody id="todos"></tbody>
    </table>

    <script src="https://code.jquery.com/jquery-3.3.1.min.js"
            integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
            crossorigin="anonymous"></script>
    <script src="site.js"></script>
</body>
</html>

將名為 site.js 的 JavaScript 檔案新增至 wwwroot 目錄。Add a JavaScript file named site.js to the wwwroot directory. 將其內容取代為下列程式碼:Replace its contents with the following code:

const uri = "api/todo";
let todos = null;
function getCount(data) {
  const el = $("#counter");
  let name = "to-do";
  if (data) {
    if (data > 1) {
      name = "to-dos";
    }
    el.text(data + " " + name);
  } else {
    el.text("No " + name);
  }
}

$(document).ready(function() {
  getData();
});

function getData() {
  $.ajax({
    type: "GET",
    url: uri,
    cache: false,
    success: function(data) {
      const tBody = $("#todos");

      $(tBody).empty();

      getCount(data.length);

      $.each(data, function(key, item) {
        const tr = $("<tr></tr>")
          .append(
            $("<td></td>").append(
              $("<input/>", {
                type: "checkbox",
                disabled: true,
                checked: item.isComplete
              })
            )
          )
          .append($("<td></td>").text(item.name))
          .append(
            $("<td></td>").append(
              $("<button>Edit</button>").on("click", function() {
                editItem(item.id);
              })
            )
          )
          .append(
            $("<td></td>").append(
              $("<button>Delete</button>").on("click", function() {
                deleteItem(item.id);
              })
            )
          );

        tr.appendTo(tBody);
      });

      todos = data;
    }
  });
}

function addItem() {
  const item = {
    name: $("#add-name").val(),
    isComplete: false
  };

  $.ajax({
    type: "POST",
    accepts: "application/json",
    url: uri,
    contentType: "application/json",
    data: JSON.stringify(item),
    error: function(jqXHR, textStatus, errorThrown) {
      alert("Something went wrong!");
    },
    success: function(result) {
      getData();
      $("#add-name").val("");
    }
  });
}

function deleteItem(id) {
  $.ajax({
    url: uri + "/" + id,
    type: "DELETE",
    success: function(result) {
      getData();
    }
  });
}

function editItem(id) {
  $.each(todos, function(key, item) {
    if (item.id === id) {
      $("#edit-name").val(item.name);
      $("#edit-id").val(item.id);
      $("#edit-isComplete")[0].checked = item.isComplete;
    }
  });
  $("#spoiler").css({ display: "block" });
}

$(".my-form").on("submit", function() {
  const item = {
    name: $("#edit-name").val(),
    isComplete: $("#edit-isComplete").is(":checked"),
    id: $("#edit-id").val()
  };

  $.ajax({
    url: uri + "/" + $("#edit-id").val(),
    type: "PUT",
    accepts: "application/json",
    contentType: "application/json",
    data: JSON.stringify(item),
    success: function(result) {
      getData();
    }
  });

  closeInput();
  return false;
});

function closeInput() {
  $("#spoiler").css({ display: "none" });
}

若要在本機測試 HTML 網頁,可能需要變更 ASP.NET Core 專案的啟動設定:A change to the ASP.NET Core project's launch settings may be required to test the HTML page locally:

  • 開啟 Properties\launchSettings.jsonOpen Properties\launchSettings.json.
  • 移除 launchUrl 屬性,以強制應用程式於 index.html 處開啟 — 專案的預設檔案。Remove the launchUrl property to force the app to open at index.html—the project's default file.

此範例會呼叫 Web API 的所有 CRUD 方法。This sample calls all of the CRUD methods of the web API. 以下是關於呼叫 API 的說明。Following are explanations of the calls to the API.

取得待辦事項的清單Get a list of to-do items

jQuery 會將 HTTP GET 要求傳送至 Web API,這會傳回代表待辦事項陣列的 JSON。jQuery sends an HTTP GET request to the web API, which returns JSON representing an array of to-do items. 如果要求成功,則會叫用 success 回呼函式。The success callback function is invoked if the request succeeds. 在回呼中,DOM 已使用待辦事項資訊進行更新。In the callback, the DOM is updated with the to-do information.

$(document).ready(function() {
  getData();
});

function getData() {
  $.ajax({
    type: "GET",
    url: uri,
    cache: false,
    success: function(data) {
      const tBody = $("#todos");

      $(tBody).empty();

      getCount(data.length);

      $.each(data, function(key, item) {
        const tr = $("<tr></tr>")
          .append(
            $("<td></td>").append(
              $("<input/>", {
                type: "checkbox",
                disabled: true,
                checked: item.isComplete
              })
            )
          )
          .append($("<td></td>").text(item.name))
          .append(
            $("<td></td>").append(
              $("<button>Edit</button>").on("click", function() {
                editItem(item.id);
              })
            )
          )
          .append(
            $("<td></td>").append(
              $("<button>Delete</button>").on("click", function() {
                deleteItem(item.id);
              })
            )
          );

        tr.appendTo(tBody);
      });

      todos = data;
    }
  });
}

新增待辦事項Add a to-do item

jQuery 會傳送 HTTP POST 要求和要求主體中的待辦事項。jQuery sends an HTTP POST request with the to-do item in the request body. acceptscontentType 選項都設定為 application/json,以指定接收和傳送的媒體類型。The accepts and contentType options are set to application/json to specify the media type being received and sent. 待辦事項會使用 JSON.stringify 轉換成 JSON。The to-do item is converted to JSON by using JSON.stringify. 當 API 傳回成功狀態碼時,會叫用 getData 函式來更新 HTML 資料表。When the API returns a successful status code, the getData function is invoked to update the HTML table.

function addItem() {
  const item = {
    name: $("#add-name").val(),
    isComplete: false
  };

  $.ajax({
    type: "POST",
    accepts: "application/json",
    url: uri,
    contentType: "application/json",
    data: JSON.stringify(item),
    error: function(jqXHR, textStatus, errorThrown) {
      alert("Something went wrong!");
    },
    success: function(result) {
      getData();
      $("#add-name").val("");
    }
  });
}

更新待辦事項Update a to-do item

更新待辦事項類似於新增待辦事項。Updating a to-do item is similar to adding one. url 會變更為新增項目的唯一識別碼,而 typePUTThe url changes to add the unique identifier of the item, and the type is PUT.

$.ajax({
  url: uri + "/" + $("#edit-id").val(),
  type: "PUT",
  accepts: "application/json",
  contentType: "application/json",
  data: JSON.stringify(item),
  success: function(result) {
    getData();
  }
});

刪除待辦事項Delete a to-do item

刪除待辦事項的達成方法是將 AJAX 呼叫的 type 設定為 DELETE,並在 URL 中指定項目的唯一識別碼。Deleting a to-do item is accomplished by setting the type on the AJAX call to DELETE and specifying the item's unique identifier in the URL.

$.ajax({
  url: uri + "/" + id,
  type: "DELETE",
  success: function(result) {
    getData();
  }
});

將驗證支援新增至 Web APIAdd authentication support to a web API

ASP.NET Core 身分識別會將使用者介面(UI)登入功能新增至 ASP.NET Core web 應用程式。ASP.NET Core Identity adds user interface (UI) login functionality to ASP.NET Core web apps. 若要保護 web Api 和 Spa,請使用下列其中一項:To secure web APIs and SPAs, use one of the following:

IdentityServer4 是適用于 ASP.NET Core 3.0 的 OpenID Connect 和 OAuth 2.0 架構。IdentityServer4 is an OpenID Connect and OAuth 2.0 framework for ASP.NET Core 3.0. IdentityServer4 可啟用下列安全性功能:IdentityServer4 enables the following security features:

  • 驗證即服務(AaaS)Authentication as a Service (AaaS)
  • 多個應用程式類型的單一登入/關閉(SSO)Single sign-on/off (SSO) over multiple application types
  • Api 的存取控制Access control for APIs
  • 同盟閘道Federation Gateway

如需詳細資訊,請參閱歡迎使用 IdentityServer4For more information, see Welcome to IdentityServer4.

其他資源Additional resources

檢視或下載本教學課程的範例程式碼View or download sample code for this tutorial. 請參閱如何下載See how to download.

如需詳細資訊,請參閱下列資源:For more information, see the following resources: