练习 - 实现 CRUD 操作

已完成

我们来继续扩展 Web API 控制器,添加在库存中创建 (POST)、更新 (PUT) 和删除 (DELETE) 披萨的功能。

添加披萨

让我们使用 POST 方法通过 Web API 添加披萨。

使用以下代码替换 Controllers/PizzaController.cs 中的 // POST action 注释:

[HttpPost]
public IActionResult Create(Pizza pizza)
{            
    PizzaService.Add(pizza);
    return CreatedAtAction(nameof(Get), new { id = pizza.Id }, pizza);
}

上一个操作:

  • 仅响应 HTTP POST 谓词,如 [HttpPost] 属性所示。
  • 将请求正文的 Pizza 对象插入到内存中缓存。

注意

由于控制器使用 [ApiController] 属性进行批注,因此意味着将在请求正文中找到 Pizza 参数。

CreatedAtAction 方法调用中的第一个参数表示操作名称。 nameof 关键字用于避免对操作名称进行硬编码。 CreatedAtAction 使用操作名称来生成 location HTTP 响应标头,该标头包含新创建的披萨的 URL,如上一个单元中介绍。

修改披萨

现在,让我们使用 PUT 方法通过 Web API 更新披萨。

使用以下代码替换 Controllers/PizzaController.cs 中的 // PUT action 注释:

[HttpPut("{id}")]
public IActionResult Update(int id, Pizza pizza)
{
    if (id != pizza.Id)
        return BadRequest();
           
    var existingPizza = PizzaService.Get(id);
    if(existingPizza is null)
        return NotFound();
   
    PizzaService.Update(pizza);           
   
    return NoContent();
}

上一个操作:

  • 仅响应 HTTP PUT 谓词,如 [HttpPut] 属性所示。
  • 要求 pizza/ 之后的 URL 段中包含 id 参数的值。
  • 返回 IActionResult,因为在运行时之前,ActionResult 返回类型未知。 BadRequestNotFoundNoContent 方法分别返回 BadRequestResultNotFoundResultNoContentResult 类型。

注意

由于控制器批注通过 [ApiController] 属性进行,因此暗示着将在请求正文中找到 Pizza 参数。

删除披萨

最后,让我们使用 DELETE 方法通过 Web API 移除披萨。

使用以下代码替换 Controllers/PizzaController.cs 中的 // DELETE action 注释:

[HttpDelete("{id}")]
public IActionResult Delete(int id)
{
    var pizza = PizzaService.Get(id);
   
    if (pizza is null)
        return NotFound();
       
    PizzaService.Delete(id);
   
    return NoContent();
}

上一个操作:

  • 仅响应 HTTP DELETE 谓词,如 [HttpDelete] 属性所示。
  • 要求 pizza/ 之后的 URL 段中包含 id 参数的值。
  • 返回 IActionResult,因为在运行时之前,ActionResult 返回类型未知。 NotFoundNoContent 方法分别返回 NotFoundResultNoContentResult 类型。
  • 查询内存中缓存以获取与所提供的 id 参数匹配的披萨。

在继续操作之前,请记得保存 Controllers/PizzaController.cs 文件。

生成并运行完成的 Web API

运行以下命令,生成并启动 Web API:

dotnet run

使用 HTTP 文件测试已完成的 Web API

  1. 重新打开 ContosoPizza.http 文件。

  2. 使用以下命令发出 POST 请求,在 HttpRepl 中添加新的披萨:

    POST {{ContosoPizza_HostAddress}}/pizza/
    Content-Type: application/json
    
    {
        "name": "Hawaii",
        "isGlutenFree": false
    }
    
    ###
    

    前面的命令将返回新创建的 Pizza:

    HTTP/1.1 201 Created
    Connection: close
    Content-Type: application/json; charset=utf-8
    Date: Wed, 17 Jan 2024 17:03:02 GMT
    Server: Kestrel
    Location: http://localhost:5192/Pizza/3
    Transfer-Encoding: chunked
    
    {
        "id": 3,
        "name": "Hawaii",
        "isGlutenFree": false
    }
    
  3. 使用以下命令发出 PUT 请求,将新的 Hawaii 披萨更新为 Hawaiian 披萨:

    PUT {{ContosoPizza_HostAddress}}/pizza/3
    Content-Type: application/json
    
    {
        "id": 3,
        "name": "Hawaiian",
        "isGlutenFree": false
    }
    
    ###
    

    前面的命令将返回以下输出,指示操作成功:

    HTTP/1.1 204 No Content
    Connection: close
    Date: Wed, 17 Jan 2024 17:07:30 GMT
    Server: Kestrel
    

    若要验证披萨是否已更新,可以使用以下命令重新运行 GET 操作:

    GET {{ContosoPizza_HostAddress}}/pizza/3
    Accept: application/json
    
    ###
    

    前面的命令将返回新更新的披萨:

    HTTP/1.1 200 OK
    Connection: close
    Content-Type: application/json; charset=utf-8
    Date: Wed, 17 Jan 2024 17:09:01 GMT
    Server: Kestrel
    Transfer-Encoding: chunked
    
    {
        "id": 3,
        "name": "Hawaiian",
        "isGlutenFree": false
    }
    
  4. 如果运行以下命令,我们的 API 还可以通过 DELETE 操作删除新创建的披萨:

    DELETE {{ContosoPizza_HostAddress}}/pizza/3
    
    ###
    

    前面的命令将返回表示成功的 204 No Content 结果:

    HTTP/1.1 204 No Content
    Date: Fri, 02 Apr 2021 23:30:04 GMT
    Server: Kestrel
    

    若要验证披萨是否已删除,可以使用以下命令重新运行 GET 操作:

    GET {{ContosoPizza_HostAddress}}/pizza/
    Accept: application/json
    
    ###
    

    前面的命令将返回原始披萨作为结果:

    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    Date: Fri, 02 Apr 2021 23:31:15 GMT
    Server: Kestrel
    Transfer-Encoding: chunked
    
    [
        {
            "id": 1,
            "name": "Classic Italian",
            "isGlutenFree": false
        },
        {
            "id": 2,
            "name": "Veggie",
            "isGlutenFree": true
        }
    ]
    

现在,你已完成了对使用 ASP.NET Core 新创建的 Web API 的实现和测试。

可选:使用命令行 HTTPREPL 测试已完成的 Web API

  1. 重新打开现有 httprepl 终端,或者通过从主菜单中选择“终端”>“新终端”,从 Visual Studio Code 中打开新的集成终端。

  2. 如果打开了新终端,请通过运行以下命令连接到 Web API:

    httprepl https://localhost:{PORT}
    

    或者,在 HttpRepl 运行时随时运行以下命令:

    connect https://localhost:{PORT}
    
  3. 运行以下命令以转到 Pizza 终结点:

    cd Pizza
    
  4. 运行以下命令,查看对披萨 API 执行的新操作:

    ls
    

    前面的命令将显示 Pizza 终结点的可用 API 的输出:

        https://localhost:{PORT}/Pizza> ls
        .      [GET|POST]
        ..     []
        {id}   [GET|PUT|DELETE]
    
  5. 使用以下命令发出 POST 请求,在 HttpRepl 中添加新的披萨:

    post -c "{"name":"Hawaii", "isGlutenFree":false}"
    

    前面的命令将返回新创建的 Pizza:

    HTTP/1.1 201 Created
    Content-Type: application/json; charset=utf-8
    Date: Fri, 02 Apr 2021 23:23:09 GMT
    Location: https://localhost:{PORT}/Pizza?id=3
    Server: Kestrel
    Transfer-Encoding: chunked
    
    {
        "id": 3,
        "name": "Hawaii",
        "isGlutenFree": false
    }
    
  6. 使用以下命令发出 PUT 请求,将新的 Hawaii 披萨更新为 Hawaiian 披萨:

    put 3 -c  "{"id": 3, "name":"Hawaiian", "isGlutenFree":false}"
    

    前面的命令将返回以下输出,指示操作成功:

    HTTP/1.1 204 No Content
    Date: Fri, 02 Apr 2021 23:23:55 GMT
    Server: Kestrel
    

    若要验证披萨是否已更新,可以使用以下命令重新运行 GET 操作:

    get 3
    

    前面的命令将返回新更新的披萨:

    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    Date: Fri, 02 Apr 2021 23:27:37 GMT
    Server: Kestrel
    Transfer-Encoding: chunked
    
    {
        "id": 3,
        "name": "Hawaiian",
        "isGlutenFree": false
    }
    
  7. 如果运行以下命令,我们的 API 还可以通过 DELETE 操作删除新创建的披萨:

    delete 3
    

    前面的命令将返回表示成功的 204 No Content 结果:

    HTTP/1.1 204 No Content
    Date: Fri, 02 Apr 2021 23:30:04 GMT
    Server: Kestrel
    

    若要验证披萨是否已删除,可以使用以下命令重新运行 GET 操作:

    get
    

    前面的命令将返回原始披萨作为结果:

    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    Date: Fri, 02 Apr 2021 23:31:15 GMT
    Server: Kestrel
    Transfer-Encoding: chunked
    
    [
        {
            "id": 1,
            "name": "Classic Italian",
            "isGlutenFree": false
        },
        {
            "id": 2,
            "name": "Veggie",
            "isGlutenFree": true
        }
    ]
    

现在,你已完成了对使用 ASP.NET Core 新创建的 Web API 的实现和测试。