使用 ASP.NET Core MVC 創(chuàng)建 Web API

2019-04-17 08:57 更新

本教程介紹使用 ASP.NET Core 構(gòu)建 Web API 的基礎(chǔ)知識(shí)。

在本教程中,你將了解:

  • 創(chuàng)建 Web API 項(xiàng)目。
  • 添加模型類。
  • 創(chuàng)建數(shù)據(jù)庫上下文。
  • 注冊(cè)數(shù)據(jù)庫上下文。
  • 添加控制器。
  • 添加 CRUD 方法。
  • 配置路由和 URL 路徑。
  • 指定返回值。
  • 使用 Postman 調(diào)用 Web API。
  • 使用 jQuery 調(diào)用 Web API。

在結(jié)束時(shí),你會(huì)獲得可以管理存儲(chǔ)在關(guān)系數(shù)據(jù)庫中的“待辦事項(xiàng)”的 Web API。

概述

本教程將創(chuàng)建以下 API:

API說明請(qǐng)求正文響應(yīng)正文
GET /api/todo獲取所有待辦事項(xiàng)None待辦事項(xiàng)的數(shù)組
GET /api/todo/{id}按 ID 獲取項(xiàng)None待辦事項(xiàng)
POST /api/todo添加新項(xiàng)待辦事項(xiàng)待辦事項(xiàng)
PUT /api/todo/{id}更新現(xiàn)有項(xiàng)  待辦事項(xiàng)None
DELETE /api/todo/{id}    刪除項(xiàng)   NoneNone

下圖顯示了應(yīng)用的設(shè)計(jì)。

客戶端提交請(qǐng)求并從應(yīng)用程序接收響應(yīng),客戶端由左側(cè)的框表示,應(yīng)用程序則由右側(cè)的框表示。

系統(tǒng)必備

創(chuàng)建 Web 項(xiàng)目

  • 從“文件”菜單中選擇“新建” > “項(xiàng)目”。
  • 選擇“ASP.NET Core Web 應(yīng)用程序”模板。 將項(xiàng)目命名為 TodoApi,然后單擊“確定”。
  • 在“新建 ASP.NET Core Web 應(yīng)用程序 - TodoApi”對(duì)話框中,選擇 ASP.NET Core 版本。 選擇“API”模板,然后單擊“確定”。 請(qǐng)不要選擇“啟用 Docker 支持”。

VS“新建項(xiàng)目”對(duì)話框

測試 API

項(xiàng)目模板會(huì)創(chuàng)建 values API。 從瀏覽器調(diào)用 Get 方法以測試應(yīng)用。

按 Ctrl+F5 運(yùn)行應(yīng)用。 Visual Studio 啟動(dòng)瀏覽器并導(dǎo)航到 https://localhost:<port>/api/values,其中 <port> 是隨機(jī)選擇的端口號(hào)。

如果出現(xiàn)詢問是否應(yīng)信任 IIS Express 證書的對(duì)話框,則選擇“是”。 在接下來出現(xiàn)的“安全警告”對(duì)話框中,選擇“是”。

會(huì)返回以下 JSON:

JSON

["value1","value2"]

添加模型類

模型是一組表示應(yīng)用管理的數(shù)據(jù)的類。 此應(yīng)用的模型是單個(gè) TodoItem 類。

  • 在“解決方案資源管理器”中,右鍵單擊項(xiàng)目。 選擇“添加” > “新建文件夾”。 將文件夾命名為“Models”。

  • 右鍵單擊“Models”文件夾,然后選擇“添加” > “類”。 將類命名為 TodoItem,然后選擇“添加”。

  • 將模板代碼替換為以下代碼:

C#

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

Id 屬性用作關(guān)系數(shù)據(jù)庫中的唯一鍵。

模型類可位于項(xiàng)目的任意位置,但按照慣例會(huì)使用 Models 文件夾。

添加數(shù)據(jù)庫上下文

數(shù)據(jù)庫上下文是為數(shù)據(jù)模型協(xié)調(diào) Entity Framework 功能的主類。 此類由 Microsoft.EntityFrameworkCore.DbContext 類派生而來。

  • 右鍵單擊“Models”文件夾,然后選擇“添加” > “類”。 將類命名為 TodoContext,然后單擊“添加”。
  • 將模板代碼替換為以下代碼:C#復(fù)制using Microsoft.EntityFrameworkCore; namespace TodoApi.Models { public class TodoContext : DbContext { public TodoContext(DbContextOptions<TodoContext> options) : base(options) { } public DbSet<TodoItem> TodoItems { get; set; } } }

注冊(cè)數(shù)據(jù)庫上下文

在 ASP.NET Core 中,服務(wù)(如數(shù)據(jù)庫上下文)必須向依賴關(guān)系注入 (DI) 容器進(jìn)行注冊(cè)。 該容器向控制器提供服務(wù)。

使用以下突出顯示的代碼更新 Startup.cs:

C#

// 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();
        }
    }
}

前面的代碼:

  • 刪除未使用的 using 聲明。
  • 將數(shù)據(jù)庫上下文添加到 DI 容器。
  • 指定數(shù)據(jù)庫上下文將使用內(nèi)存中數(shù)據(jù)庫。

添加控制器

  • 右鍵單擊 Controllers 文件夾。

  • 選擇 添加 > 新建項(xiàng)

  • 在“添加新項(xiàng)”對(duì)話框中,選擇“API 控制器類”模板。

  • 將類命名為 TodoController,然后選擇“添加”。

    “添加新項(xiàng)”對(duì)話框,“控制器”顯示在搜索框中,并且“Web API 控制器”已選中

  • 將模板代碼替換為以下代碼:C#復(fù)制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(); } } } }

前面的代碼:

  • 定義了沒有方法的 API 控制器類。
  • 使用 [ApiController] 屬性修飾類。 此屬性指示控制器響應(yīng) Web API 請(qǐng)求。 有關(guān)該屬性啟用的特定行為的信息,請(qǐng)參閱使用 ApiController 屬性進(jìn)行注釋。
  • 使用 DI 將數(shù)據(jù)庫上下文 (TodoContext) 注入到控制器中。 數(shù)據(jù)庫上下文將在控制器中的每個(gè) CRUD 方法中使用。
  • 如果數(shù)據(jù)庫為空,則將名為 Item1 的項(xiàng)添加到數(shù)據(jù)庫。 此代碼位于構(gòu)造函數(shù)中,因此在每次出現(xiàn)新 HTTP 請(qǐng)求時(shí)運(yùn)行。 如果刪除所有項(xiàng),則構(gòu)造函數(shù)會(huì)在下次調(diào)用 API 方法時(shí)再次創(chuàng)建 Item1。 因此刪除可能看上去不起作用,不過實(shí)際上確實(shí)有效。

添加 Get 方法

若要提供檢索待辦事項(xiàng)的 API,請(qǐng)將以下方法添加到 TodoController 類中:

C#

// 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;
}

這些方法實(shí)現(xiàn)兩個(gè) GET 終結(jié)點(diǎn):

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

通過從瀏覽器調(diào)用兩個(gè)終結(jié)點(diǎn)來測試應(yīng)用。 例如:

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

以下 HTTP 響應(yīng)通過調(diào)用 GetTodoItems 來生成:

JSON

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

路由和 URL 路徑

[HttpGet] 屬性表示響應(yīng) HTTP GET 請(qǐng)求的方法。 每個(gè)方法的 URL 路徑構(gòu)造如下所示:

  • 在控制器的 Route 屬性中以模板字符串開頭:C#復(fù)制namespace TodoApi.Controllers { [Route("api/[controller]")] [ApiController] public class TodoController : ControllerBase { private readonly TodoContext _context;
  • 將 [controller] 替換為控制器的名稱,按照慣例,在控制器類名稱中去掉“Controller”后綴。對(duì)于此示例,控制器類名稱為“Todo”控制器,因此控制器名稱為“todo”。 ASP.NET Core 路由不區(qū)分大小寫。
  • 如果 [HttpGet] 屬性具有路由模板(例如 [HttpGet("products")]),則將它追加到路徑。 此示例不使用模板。 有關(guān)詳細(xì)信息,請(qǐng)參閱使用 Http [Verb] 特性的特性路由。

在下面的 GetTodoItem 方法中,"{id}" 是待辦事項(xiàng)的唯一標(biāo)識(shí)符的占位符變量。 調(diào)用 GetTodoItem 時(shí),URL 中 "{id}" 的值會(huì)在 id 參數(shù)中提供給方法。

C#

// 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;
}

返回值

GetTodoItems 和 GetTodoItem 方法的返回類型是 ActionResult<T> 類型。 ASP.NET Core 自動(dòng)將對(duì)象序列化為 JSON,并將 JSON 寫入響應(yīng)消息的正文中。 在假設(shè)沒有未經(jīng)處理的異常的情況下,此返回類型的響應(yīng)代碼為 200。 未經(jīng)處理的異常將轉(zhuǎn)換為 5xx 錯(cuò)誤。

ActionResult 返回類型可以表示大范圍的 HTTP 狀態(tài)代碼。 例如,GetTodoItem 可以返回兩個(gè)不同的狀態(tài)值:

  • 如果沒有任何項(xiàng)與請(qǐng)求的 ID 匹配,則該方法將返回 404 NotFound 錯(cuò)誤代碼。
  • 否則,此方法將返回具有 JSON 響應(yīng)正文的 200。 返回 item 則產(chǎn)生 HTTP 200 響應(yīng)。

測試 GetTodoItems 方法

本教程使用 Postman 測試 Web API。

  • 安裝 Postman
  • 啟動(dòng) Web 應(yīng)用。
  • 啟動(dòng) Postman。
  • 禁用 SSL 證書驗(yàn)證在“文件”>“設(shè)置”(“常規(guī)”*選項(xiàng)卡)中,禁用“SSL 證書驗(yàn)證”。 警告在測試控制器之后重新啟用 SSL 證書驗(yàn)證。
  • 創(chuàng)建新請(qǐng)求。將 HTTP 方法設(shè)置為“GET”。將請(qǐng)求 URL 設(shè)置為 https://localhost:<port>/api/todo。 例如 https://localhost:5001/api/todo。
  • 在 Postman 中設(shè)置“兩窗格視圖”。
  • 選擇“發(fā)送”。

使用 Get 請(qǐng)求的 Postman

添加創(chuàng)建方法

添加以下 PostTodoItem 方法:

C#

// 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);
}

正如 [HttpPost] 屬性所指示,前面的代碼是 HTTP POST 方法。 該方法從 HTTP 請(qǐng)求正文獲取待辦事項(xiàng)的值。

CreatedAtAction 方法:

  • 如果成功,則返回 HTTP 201 狀態(tài)代碼。 HTTP 201 是在服務(wù)器上創(chuàng)建新資源的 HTTP POST 方法的標(biāo)準(zhǔn)響應(yīng)。
  • 將 Location 標(biāo)頭添加到響應(yīng)。 Location 標(biāo)頭指定新建的待辦事項(xiàng)的 URI。 有關(guān)詳細(xì)信息,請(qǐng)參閱創(chuàng)建的 10.2.2 201。
  • 引用 GetTodoItem 操作以創(chuàng)建 Location 標(biāo)頭的 URI。 C# nameof 關(guān)鍵字用于避免在 CreatedAtAction 調(diào)用中硬編碼操作名稱。C#復(fù)制// 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 方法

  • 生成項(xiàng)目。
  • 在 Postman 中,將 HTTP 方法設(shè)置為 POST。
  • 選擇“正文”選項(xiàng)卡。
  • 選擇“原始”單選按鈕。
  • 將類型設(shè)置為 JSON (application/json)
  • 在請(qǐng)求正文中,輸入待辦事項(xiàng)的 JSON:JSON復(fù)制{ "name":"walk dog", "isComplete":true }
  • 選擇“發(fā)送”。使用創(chuàng)建請(qǐng)求的 Postman如果收到 405 不允許的方法錯(cuò)誤,則可能是由于未在添加 PostTodoItem 方法之后編譯項(xiàng)目。

測試位置標(biāo)頭 URI

  • 在“響應(yīng)”窗格中選擇“標(biāo)頭”選項(xiàng)卡。
  • 復(fù)制“位置”標(biāo)頭值:Postman 控制臺(tái)的“標(biāo)頭”選項(xiàng)卡
  • 將方法設(shè)置為“GET”。
  • 粘貼 URI(例如,https://localhost:5001/api/Todo/2)
  • 選擇“發(fā)送”。

添加 PutTodoItem 方法

添加以下 PutTodoItem 方法:

C#

// 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。 響應(yīng)是 204(無內(nèi)容)。 根據(jù) HTTP 規(guī)范,PUT 請(qǐng)求需要客戶端發(fā)送整個(gè)更新的實(shí)體,而不僅僅是更改。 若要支持部分更新,請(qǐng)使用 HTTP PATCH。

如果在調(diào)用 PutTodoItem 時(shí)出錯(cuò),請(qǐng)調(diào)用 GET 以確保數(shù)據(jù)庫中有項(xiàng)目。

測試 PutTodoItem 方法

本示例使用內(nèi)存數(shù)據(jù)庫,每次啟動(dòng)應(yīng)用時(shí)都必須對(duì)其進(jìn)行初始化。 在進(jìn)行 PUT 調(diào)用之前,數(shù)據(jù)庫中必須有一個(gè)項(xiàng)。 調(diào)用 GET 以確保在進(jìn)行 PUT 調(diào)用之前數(shù)據(jù)庫中有一個(gè)項(xiàng)。

更新 id = 1 的待辦事項(xiàng)并將其名稱設(shè)置為“feed fish”:

JSON

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

下圖顯示 Postman 更新:

顯示 204(無內(nèi)容)響應(yīng)的 Postman 控制臺(tái)

添加 DeleteTodoItem 方法

添加以下 DeleteTodoItem 方法:

C#

// 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 響應(yīng)是 204(無內(nèi)容)。

測試 DeleteTodoItem 方法

使用 Postman 刪除待辦事項(xiàng):

  • 將方法設(shè)置為 DELETE。
  • 設(shè)置要?jiǎng)h除的對(duì)象的 URI,例如 https://localhost:5001/api/todo/1
  • 選擇“Send”

示例應(yīng)用允許刪除所有項(xiàng),但是在刪除最后一項(xiàng)后,模型類構(gòu)造函數(shù)會(huì)在下次調(diào)用 API 時(shí)創(chuàng)建一個(gè)新項(xiàng)。

使用 jQuery 調(diào)用 API

在本部分中,添加了使用 jQuery 調(diào)用 Web API 的 HTML 頁面。 jQuery 啟動(dòng)請(qǐng)求,并用 API 響應(yīng)中的詳細(xì)信息更新頁面。

配置應(yīng)用提供靜態(tài)文件啟用默認(rèn)文件映射

C#

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();
}

在項(xiàng)目目錄中創(chuàng)建 wwwroot 文件夾。

將一個(gè)名為 index.html 的 HTML 文件添加到 wwwroot 目錄。 用以下標(biāo)記替代其內(nèi)容:

HTML

<!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" rel="external nofollow" 
            integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
            crossorigin="anonymous"></script>
    <script src="site.js"></script>
</body>
</html>

將名為 site.js 的 JavaScript 文件添加到 wwwroot 目錄。 用以下代碼替代其內(nèi)容:

JavaScript

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" });
}

可能需要更改 ASP.NET Core 項(xiàng)目的啟動(dòng)設(shè)置,以便對(duì) HTML 頁面進(jìn)行本地測試:

  • 打開 Properties\launchSettings.json。
  • 刪除 launchUrl 以便在項(xiàng)目的默認(rèn)文件 index.html 強(qiáng)制打開應(yīng)用。

有多種方式可以獲取 jQuery。 在前面的代碼片段中,庫是從 CDN 中加載的。

此示例調(diào)用 API 的所有 CRUD 方法。 以下是 API 調(diào)用的說明。

獲取待辦事項(xiàng)的列表

jQuery ajax 函數(shù)將 GET 請(qǐng)求發(fā)送至 API,這將返回表示待辦事項(xiàng)數(shù)組的 JSON。 如果請(qǐng)求成功,則調(diào)用 success 回調(diào)函數(shù)。 在該回調(diào)中使用待辦事項(xiàng)信息更新 DOM。

JavaScript

$(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;
    }
  });
}

添加待辦事項(xiàng)

Ajax 函數(shù)發(fā)送 POST,請(qǐng)求正文中包含待辦事項(xiàng)。 將 accepts 和 contentType 選項(xiàng)設(shè)置為 application/json,以便指定接收和發(fā)送的媒體類型。 待辦事項(xiàng)使用 JSON.stringify 轉(zhuǎn)換為 JSON。當(dāng) API 返回成功狀態(tài)的代碼時(shí),將調(diào)用 getData 函數(shù)來更新 HTML 表。

JavaScript

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("");
    }
  });
}

更新待辦事項(xiàng)

更新待辦事項(xiàng)與添加類似。 url 更改為添加項(xiàng)的唯一標(biāo)識(shí)符,并且 type 為 PUT。

JavaScript

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

刪除待辦事項(xiàng)

若要?jiǎng)h除待辦事項(xiàng),請(qǐng)將 AJAX 調(diào)用上的 type 設(shè)為 DELETE 并指定該項(xiàng)在 URL 中的唯一標(biāo)識(shí)符。

JavaScript

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


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)