Asp.Net创建控制台程序和WebAPI

1. 控制台程序

我们将使用一个控制台应用程序,用于整合各种中间件,Web API也是一样的方式。

shell 复制代码
 dotnet new console --name SportsStatsTracker

数据库链接地址和账户密码登不能直接写到代码里面,所以需要添加读取 JSON 配置文件的支持。

shell 复制代码
 dotnet add package Microsoft.Extensions.Configuration.Json

在编辑器中,选择SportsStatsTracker.csproj文件以打开它。

将以下 <ItemGroup> 配置块添加到 <PropertyGroup> 元素下方的根 <Project> 元素中。 此配置将在项目中包含新文件,并将其复制到输出文件夹。 此块中的指令可以确保在编译/生成应用时将应用配置文件放在输出目录中。

xml 复制代码
 <Project Sdk="Microsoft.NET.Sdk">
 ​
   <PropertyGroup>
       ...
   </PropertyGroup>
 ​
   <ItemGroup>
      <None Update="appsettings.json">
        <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      </None>
   </ItemGroup>
 ​
 </Project>

现已添加用于启用读取配置所需的库,我们需要在控制台应用程序中启用该功能。在编辑器中,选择Program.cs,将文件的内容替换为以下代码。

C# 复制代码
 using Microsoft.Extensions.Configuration;
 ​
 namespace SportsStatsTracker
 {
     class Program
     {
         static void Main(string[] args)
         {
             var config = new ConfigurationBuilder()
                 .SetBasePath(Directory.GetCurrentDirectory())
                 .AddJsonFile("appsettings.json")
                 .Build();
             
             string connectionString = config["CacheConnection"];
         }
     }
 }

① 连接Redis

添加对 Redis 缓存 .NET 客户端的支持。

shell 复制代码
 dotnet add package StackExchange.Redis

接下来,将控制台应用程序配置为使用适用于 .NETStackExchange.Redis 客户端。

C# 复制代码
 using Microsoft.Extensions.Configuration;
 using StackExchange.Redis;
 ​
 namespace SportsStatsTracker
 {
    class Program
    {
       static async Task Main(string[] args)
       {
          var config = new ConfigurationBuilder()
             .SetBasePath(Directory.GetCurrentDirectory())
             .AddJsonFile("appsettings.json")
             .Build();
 ​
          string connectionString = config["CacheConnection"];
 ​
          using (var cache = ConnectionMultiplexer.Connect(connectionString))
          {
             IDatabase db = cache.GetDatabase();
 ​
             bool setValue = db.StringSet("test:key", "some value");
             Console.WriteLine($"SET: {setValue}");
 ​
             string getValue = db.StringGet("test:key");
             Console.WriteLine($"GET: {getValue}");
 ​
             setValue = await db.StringSetAsync("counter", "100");
             Console.WriteLine($"SET: {setValue}");
 ​
             getValue = await db.StringGetAsync("counter");
             Console.WriteLine($"GET: {getValue}");
 ​
             long newValue = await db.StringIncrementAsync("counter", 50);
             Console.WriteLine($"INCR new value = {newValue}");  
 ​
             var result = await db.ExecuteAsync("ping");
             Console.WriteLine($"PING = {result.Type} : {result}");
 ​
             result = await db.ExecuteAsync("flushdb");
             Console.WriteLine($"FLUSHDB = {result.Type} : {result}");
          }
       }
    }
 }

② 连接SQL Server

③ 连接MySQL

2. Web API

本模块使用.NET 8.0 SDK。 通过在首选命令终端中运行以下命令,确保你已安装 .NET 8.0

shell 复制代码
 dotnet --list-sdks

将显示类似于以下示例的输出:

shell 复制代码
 6.0.317 [C:\Program Files\dotnet\sdk]
 7.0.401 [C:\Program Files\dotnet\sdk]
 8.0.100 [C:\Program Files\dotnet\sdk]

确保列出了以 8 开头的版本。 如果未列出任何版本或未找到命令,请安装最新的 .NET 8.0 SDK

① 创建并浏览 Web API 项目

shell 复制代码
 dotnet new webapi -controllers --name CsharpWebAPI -f net8.0

默认使用 https 保护 Web API 项目,.NET Core SDK 包含 HTTPS 开发证书。 该证书是作为首次运行体验的一部分安装的。

例如:dotnet --info 会生成以下输出的变体:

shell 复制代码
 ASP.NET Core
 ------------
 Successfully installed the ASP.NET Core HTTPS Development Certificate.
 To trust the certificate run 'dotnet dev-certs https --trust' (Windows and macOS only).
 For establishing trust on other platforms refer to the platform specific documentation.
 For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054.

安装 .NET Core SDK 会将 ASP.NET Core HTTPS 开发证书安装到本地用户证书存储。 该证书已安装,但它不受信任。 若要信任该证书,请执行一次性步骤,以运行 dotnet dev-certs 工具:

shell 复制代码
 dotnet dev-certs https --trust

下面的命令提供有关 dev-certs 工具的帮助:

shell 复制代码
 dotnet dev-certs https --help

② 执行dotnet run运行项目。

上述命令:

  • 在当前目录中找到项目文件。
  • 检索并安装此项目所需的任何项目依赖项。
  • 编译项目代码。
  • 使用 ASP.NET Core Kestrel Web 服务器将 Web API 托管在 HTTPHTTPS终结点中。

创建项目时,将为 HTTP 选择 50005300 端口,为 HTTPS 选择 70007300 端口。 通过编辑项目的 launchSettings.json 文件,可以轻松更改开发过程中使用的端口。 本模块使用以 https 开头的安全 localhost URL。

应获得类似于以下内容的输出,用于指示应用正在运行:

shell 复制代码
 PS E:\code\source\CsharpWebAPI> dotnet run
 正在生成...
 info: Microsoft.Hosting.Lifetime[14]
       Now listening on: http://localhost:5166
 info: Microsoft.Hosting.Lifetime[0]
       Application started. Press Ctrl+C to shut down.
 info: Microsoft.Hosting.Lifetime[0]
       Hosting environment: Development
 info: Microsoft.Hosting.Lifetime[0]
       Content root path: E:\code\source\CsharpWebAPI 

如果你是在自己的计算机上运行此应用,可以将浏览器指向输出中显示的 HTTPS 链接(在上例中为 https://localhost:7294)以查看生成的页面。 请记住此端口,因为在使用 {PORT} 的整个模块中将一直使用它。

③ 打开 Web 浏览器并转到:https://localhost:{PORT}/weatherforecast

应会看到类似于这个示例的 JSON 输出:

json 复制代码
 [{"date":"2024-02-28","temperatureC":2,"summary":"Bracing","temperatureF":35},{"date":"2024-02-29","temperatureC":-7,"summary":"Chilly","temperatureF":20},{"date":"2024-03-01","temperatureC":50,"summary":"Cool","temperatureF":121},{"date":"2024-03-02","temperatureC":36,"summary":"Bracing","temperatureF":96},{"date":"2024-03-03","temperatureC":-9,"summary":"Bracing","temperatureF":16}]

④ 使用 .http 文件进行测试接口

项目中包含的文件为 CsharpWebAPI.http,该文件用于通过标准格式测试 API 终结点。 多个 IDE 都支持 .http 文件,包括 Visual Studio 以及安装了 REST 客户端扩展的 Visual Studio Code 内部。

  1. 打开 CsharpWebAPI.http 文件。

    此文件已预配置了 @ContosoPizza_HostAddress 变量和调用 /weatherforecast/ 的 GET 命令,该命令接受application/json

  2. 选择 GET 上方的"发送请求"命令,该命令会将请求发送到正在运行的服务。

    调用此命令将打开一个响应窗口,其输出与我们在浏览器中看到的以下内容类似:

    json 复制代码
     HTTP/1.1 200 OK
     connection: close
     content-type: application/json; charset=utf-8
     date: Tue, 27 Feb 2024 07:30:16 GMT
     server: Kestrel
     transfer-encoding: chunked
     ​
     [
       {
         "date": "2024-02-28",
         "temperatureC": 19,
         "temperatureF": 66,
         "summary": "Warm"
       },
       {
         "date": "2024-02-29",
         "temperatureC": 48,
         "temperatureF": 118,
         "summary": "Chilly"
       },
       {
         "date": "2024-03-01",
         "temperatureC": 28,
         "temperatureF": 82,
         "summary": "Bracing"
       },
       {
         "date": "2024-03-02",
         "temperatureC": 52,
         "temperatureF": 125,
         "summary": "Bracing"
       },
       {
         "date": "2024-03-03",
         "temperatureC": 51,
         "temperatureF": 123,
         "summary": "Bracing"
       }
     ]

    你创建了一个 Web 应用程序,用于提供示例天气预报数据,然后,你使用了 .HTTP 与该应用程序交互。

    示例方案

    假设你是一家名为 Contoso Pizza 的披萨公司的员工。 经理要求你为披萨库存管理开发一个 RESTful 服务,作为公司 Web店面和移动应用程序的必备组件。 该服务必须支持添加、查看、修改和删除披萨类型;HTTP 谓词的标准化使用方式,也称为创建、读取、更新、删除 (CRUD)。

    在深入探讨如何编写自己的 PizzaController 类之前,让我们先看一下 WeatherController 示例中的代码,了解它的工作原理。 在本单元中,你将了解 WeatherController 如何在几十行代码中使用 ControllerBase 基类和几个.NET 属性来生成正常工作的 Web API。 了解这些概念后,便可以编写自己的 PizzaController 类了。

    以下是整个 WeatherController 类的代码。 如果你还不明白,请不要担心。 现在来逐步完成这一过程。

    C# 复制代码
     using Microsoft.AspNetCore.Mvc;
     ​
     namespace ContosoPizza.Controllers;
     ​
     [ApiController]
     [Route("[controller]")]
     public class WeatherForecastController : ControllerBase
     {
         private static readonly string[] Summaries = new[]
         {
             "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
         };
     ​
         private readonly ILogger<WeatherForecastController> _logger;
     ​
         public WeatherForecastController(ILogger<WeatherForecastController> logger)
         {
             _logger = logger;
         }
     ​
         [HttpGet(Name = "GetWeatherForecast")]
         public IEnumerable<WeatherForecast> Get()
         {
             return Enumerable.Range(1, 5).Select(index => new WeatherForecast
             {
                 Date = DateTime.Now.AddDays(index),
                 TemperatureC = Random.Shared.Next(-20, 55),
                 Summary = Summaries[Random.Shared.Next(Summaries.Length)]
             })
             .ToArray();
         }
     }

    基类:ControllerBase

    控制器是一个公共类,具有一个或多个称为"操作"的公共方法。 按照惯例,控制器放在项目根目录的 Controllers 目录中。 操作通过路由被公开为 HTTP 终结点。 因此,对 https://localhost:{PORT}/weatherforecast 的 HTTP GET 请求将执行 WeatherForecastController 类的 Get() 方法。

    首先要注意的是,此类继承自 ControllerBase 基类。 这个基类提供了许多用于处理 HTTP 请求的标准功能,让你可以专注于应用程序的特定业务逻辑。

    如果你在 ASP.NET Core 中开发过 Razor Pages 或模型-视图-控制器 (MVC) 体系结构,那么你已使用过 Controller 类。 不要通过从 Controller 类派生来创建 Web API 控制器。 Controller 派生自 ControllerBase,并添加了对视图的支持,因此它用于处理网页,而不是 Web API 请求。

    API 控制器类属性

    有两个重要属性应用到了 WeatherForecastController,如以下代码所示:

    C# 复制代码
     [ApiController]
     [Route("[controller]")]
     public class WeatherForecastController : ControllerBase

    [ApiController] 启用固定行为,使生成 Web API 更加容易。 一些行为包括参数源推理、将属性路由作为一项要求以及模型验证错误处理增强功能。

    [Route] 定义路由模式 [controller][controller] 令牌替换为用控制器的名称(不区分大小写,无 Controller 后缀)。 此控制器处理对 https://localhost:{PORT}/weatherforecast 的请求。

    路由可能包含静态字符串,如 api/[controller] 中所示。 在此示例中,此控制器将处理对 https://localhost:{PORT}/api/weatherforecast 的请求。

    使用 Get() 方法提供天气预报结果

    WeatherForecastController 包括由 [HttpGet(Name = "GetWeatherForecast")] 属性指定的单个控制器操作。 此属性将 HTTP GET 请求路由到 public IEnumerable<WeatherForecast> Get() 方法。 如你所见,在上一个练习中,向 https://localhost:{PORT}/weatherforecast 发出请求会导致返回天气预报结果。

    本模块的后面部分会介绍其他常见操作与执行 CRUD 操作(GETPUTPOSTDELETE)的Web API 相关联。 但 API 控制器只需要实现一个控制器操作。

    在本例中,你将获取返回的 WeatherForecast 的完整列表。 GET 操作还允许通过传递标识符来检索单个项。 在 ASP.NET 中,可以使用 [HttpGet("{id}")] 特性检索单个项。 在下一练习中将实现该属性。

⑤ 现在,你已了解了 Web API 控制器的基本组件,现在可以创建自己的 PizzaController 类了。

在开始为披萨实现 Web API 之前,需要添加一个数据存储供你执行操作。

你需要一个 model 类来表示库存中的披萨。 模型包含用于表示披萨特征的属性。 模型用于在 Web API 中传递数据,以及在数据存储中保存披萨选项。

在本单元中,该数据存储是一个简单的本地内存中缓存服务。 在实际应用程序中,可以考虑将数据库(例如 SQL Server)与 Entity Framework Core 结合使用。

1. 创建披萨模型

shell 复制代码
 # 创建 Models 文件夹:
 mkdir Models

将以下代码添加到Models/Pizza.cs并保存所做的更改。 此类定义披萨。

C# 复制代码
 namespace CsharpWebAPI.Models;
 ​
 public class Pizza
 {
     public int Id { get; set; }
     public string? Name { get; set; }
     public bool IsGlutenFree { get; set; }
 }

2. 添加数据服务

shell 复制代码
 # 创建 Services 文件夹
 mkdir Services

将以下代码添加到Services/PizzaService.cs并保存所做的更改。 此代码创建内存中披萨数据服务。

C# 复制代码
 using CsharpWebAPI.Models;
 ​
 namespace CsharpWebAPI.Services;
 ​
 public static class PizzaService
 {
     static List<Pizza> Pizzas { get; }
     static int nextId = 3;
     static PizzaService()
     {
         Pizzas = new List<Pizza>
         {
             new Pizza { Id = 1, Name = "Classic Italian", IsGlutenFree = false },
             new Pizza { Id = 2, Name = "Veggie", IsGlutenFree = true }
         };
     }
 ​
     public static List<Pizza> GetAll() => Pizzas;
 ​
     public static Pizza? Get(int id) => Pizzas.FirstOrDefault(p => p.Id == id);
 ​
     public static void Add(Pizza pizza)
     {
         pizza.Id = nextId++;
         Pizzas.Add(pizza);
     }
 ​
     public static void Delete(int id)
     {
         var pizza = Get(id);
         if(pizza is null)
             return;
 ​
         Pizzas.Remove(pizza);
     }
 ​
     public static void Update(Pizza pizza)
     {
         var index = Pizzas.FindIndex(p => p.Id == pizza.Id);
         if(index == -1)
             return;
 ​
         Pizzas[index] = pizza;
     }
 }

默认情况下,此服务提供一个简单的内存中数据缓存服务,其中包含两个披萨。 我们的 Web API 使用该服务进行演示。 如果先停止再启动 Web API,内存中数据缓存会重置为PizzaService的构造函数中的两个默认披萨。

⑥ 运行dotnet build以生成应用:生成成功,且没有任何警告。 如果生成失败,请检查输出以获取故障排除信息。

控制器是一个公共类,具有一个或多个称为"操作"的公共方法。 按照惯例,控制器放在项目根目录的 Controllers 目录中。 这些操作在 Web API 控制器内公开为 HTTP 终结点。

添加控制器

Visual Studio Code 中选择 Controllers 文件夹,并添加名为 PizzaController.cs 的新文件。

C# 复制代码
 using CsharpWebAPI.Models;
 using CsharpWebAPI.Services;
 using Microsoft.AspNetCore.Mvc;
 ​
 namespace CsharpWebAPI.Controllers;
 ​
 [ApiController]
 [Route("[controller]")]
 public class PizzaController : ControllerBase
 {
     public PizzaController()
     {
     }
 ​
     // GET all action
 ​
     // GET by Id action
 ​
     // POST action
 ​
     // PUT action
 ​
     // DELETE action
 }

如前文所述,此类派生自 ControllerBase,后者是 ASP.NET Core 中用于处理 HTTP 请求的基类。 它还包含你已经了解的两个标准属性,即 [ApiController][Route]。 如前文所述,[Route] 属性定义了到 [controller] 令牌的映射。 由于此控制器类名为 PizzaController,因此该控制器处理对 https://localhost:{PORT}/pizza 的请求。

获取所有披萨

需要实现的第一个 REST 谓词是 GET,使用该谓词,客户端可以从 API 获取所有披萨。 可使用内置 [HttpGet] 属性来定义从服务返回披萨的方法。

Controllers/PizzaController.cs 中的 // GET all action 注释替换为以下代码:

C# 复制代码
 [HttpGet]
 public ActionResult<List<Pizza>> GetAll() =>
     PizzaService.GetAll();

上一个操作:

  • 仅响应 HTTP GET 谓词,如 [HttpGet] 属性所示。
  • 返回类型为 List<Pizza>ActionResult 实例。 ActionResult 类型是 ASP.NET Core 中所有操作结果的基类。
  • 查询服务以获取所有披萨,并通过 Content-Type 的值 application/json 自动返回数据。

3. 检索单种披萨

客户端可能还需要请求获取特定披萨而非整个列表的相关信息。 你可以实现另一个 GET 操作,此操作需要 id 参数。 可使用内置 [HttpGet("{id}")] 属性来定义从服务返回披萨的方法。 路由逻辑将 [HttpGet](没有 id)和 [HttpGet("{id}")](具有 id)注册为两个不同的路由。 然后,你可以编写一个单独的操作来检索单个项。

Controllers/PizzaController.cs 中的 // GET by Id action 注释替换为以下代码:

C# 复制代码
 [HttpGet("{id}")]
 public ActionResult<Pizza> Get(int id)
 {
     var pizza = PizzaService.Get(id);
 ​
     if(pizza == null)
         return NotFound();
 ​
     return pizza;
 }

上一个操作:

  • 仅响应 HTTP GET 谓词,如 [HttpGet] 属性所示。
  • 要求 pizza/ 之后的 URL 段中包含 id 参数的值。 请记住,控制器级别的 [Route]属性定义了/pizza模式。
  • 查询数据库以获取与所提供的 id 参数匹配的披萨。

上述操作中使用的每个 ActionResult 实例都映射到下表中对应的 HTTP 状态代码:

ASP.NET Core 操作结果 HTTP 状态代码 说明
Ok 为隐式 200 内存中缓存中存在与所提供的 id 参数匹配的产品。 该产品包含在由 accept HTTP 请求标头中所定义的媒体类型(默认情况下为 JSON)的响应正文中。
NotFound 404 内存中缓存中不存在与所提供的 id 参数匹配的产品。

4. 生成并运行新控制器

运行以下命令,生成并启动 Web APIdotnet run

5. 使用.http 文件测试控制器

  1. 打开 CsharpWebAPI.http
  2. 添加新的 GET 以在 ### 分隔符下调用 Pizza 终结点:
http 复制代码
 @CsharpWebAPI_HostAddress = http://localhost:5166
 ​
 GET {{CsharpWebAPI_HostAddress}}/weatherforecast/
 Accept: application/json
 ​
 ###
 ​
 GET {{CsharpWebAPI_HostAddress}}/Pizza/
 Accept: application/json
 ​
 ###
 ​
 GET {{CsharpWebAPI_HostAddress}}/Pizza/1
 Accept: application/json

ASP.NET Core 中的 CRUD 操作

我们的披萨服务支持对披萨列表执行 CRUD 操作。 这些操作是通过 HTTP 谓词执行的,它们通过 ASP.NET Core 属性进行映射。 正如你所了解的,HTTP GET 谓词用于从服务检索一个或多个项。 此类操作使用 [HttpGet] 属性进行批注。

下表显示了你为披萨服务实现的四个操作的映射:

HTTP 操作谓词 CRUD 操作 ASP.NET Core 属性
GET 读取 [HttpGet]
POST 创建 [HttpPost]
PUT Update [HttpPut]
DELETE 删除 [HttpDelete]

你已经了解了 GET 操作的工作原理。 让我们来详细了解一下 POSTPUTDELETE 操作。

POST

为了使用户能够将新项添加到终结点,必须通过使用 [HttpPost] 属性来实现 POST 操作。 将项(在此示例中是披萨)作为参数传递入方法时,ASP.NET Core 会自动将发送到终结点的任何应用程序/JSON 转换为填充的 .NET Pizza 对象。

以下是 Create 方法的方法签名,你将在下一节中实现该方法:

c# 复制代码
 [HttpPost]
 public IActionResult Create(Pizza pizza)
 {            
     // This code will save the pizza and return a result
 }

[HttpPost] 属性使用 Create() 方法映射发送到 http://localhost:5000/pizza 的 HTTP POST 请求。 此方法并不像我们在 Get() 方法中看到的那样返回披萨列表,而是返回 IActionResult 响应。

IActionResult 可让客户端知道请求是否成功,并提供新创建的披萨的 IDIActionResult 使用标准 HTTP 状态代码,因此,无论客户端使用哪种语言或者在哪个平台上运行,它都能轻松地与客户端集成。

ASP.NET Core 操作结果 HTTP 状态代码 说明
CreatedAtAction 201 已将披萨添加到内存中缓存。 该披萨包含在由 accept HTTP 请求标头中所定义的媒体类型(默认情况下为 JSON)的响应正文中。
BadRequest 为隐式 400 请求正文的 pizza 对象无效。

幸运的是,ControllerBase 具有一些实用工具方法,它们可为你创建适当的 HTTP 响应代码和消息。

PUT

修改或更新库存中的披萨类似于我们实现的 POST 方法,但它使用 [HttpPut] 属性并接受 id 参数以及需要更新的 Pizza 对象:

c# 复制代码
 [HttpPut("{id}")]
 public IActionResult Update(int id, Pizza pizza)
 {
     // This code will update the pizza and return a result
 }

上述操作中使用的每个 ActionResult 实例都映射到下表中对应的 HTTP 状态代码:

展开表

ASP.NET Core 操作结果 HTTP 状态代码 说明
NoContent 204 已在内存中缓存中更新了披萨。
BadRequest 400 请求正文的 Id 值与路由的 id 值不匹配。
BadRequest 为隐式 400 请求正文的 Pizza 对象无效。

DELETE

可实现的一种更简单的操作是 DELETE 操作,该操作只接受要从内存中缓存中删除的披萨的 id 参数:

c# 复制代码
 [HttpDelete("{id}")]
 public IActionResult Delete(int id)
 {
     // This code will delete the pizza and return a result
 }

上述操作中使用的每个 ActionResult 实例都映射到下表中对应的 HTTP 状态代码:

ASP.NET Core 操作结果 HTTP 状态代码 说明
NoContent 204 已从内存中缓存中删除了披萨。
NotFound 404 内存中缓存中不存在与所提供的 id 参数匹配的披萨。

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

添加披萨

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

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

c# 复制代码
 [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 注释:

c# 复制代码
 [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 注释:

c# 复制代码
 [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 APIdotnet run

最后测试文档如下:

http 复制代码
 @CsharpWebAPI_HostAddress = http://localhost:5166
 ​
 GET {{CsharpWebAPI_HostAddress}}/weatherforecast/
 Accept: application/json
 ​
 ###
 ​
 GET {{CsharpWebAPI_HostAddress}}/Pizza/
 Accept: application/json
 ​
 ###
 ​
 GET {{CsharpWebAPI_HostAddress}}/Pizza/1
 Accept: application/json
 ​
 ###
 POST {{CsharpWebAPI_HostAddress}}/pizza/
 Content-Type: application/json
 ​
 {
     "name": "Hawaii",
     "isGlutenFree": false
 }
 ​
 ###
 PUT {{CsharpWebAPI_HostAddress}}/pizza/3
 Content-Type: application/json
 ​
 {
     "id": 3,
     "name": "Hawaiian",
     "isGlutenFree": false
 }
 ​
 ###
 DELETE {{CsharpWebAPI_HostAddress}}/pizza/3
相关推荐
姜学迁17 分钟前
Rust-枚举
开发语言·后端·rust
【D'accumulation】1 小时前
令牌主动失效机制范例(利用redis)注释分析
java·spring boot·redis·后端
2401_854391081 小时前
高效开发:SpringBoot网上租赁系统实现细节
java·spring boot·后端
Cikiss1 小时前
微服务实战——SpringCache 整合 Redis
java·redis·后端·微服务
Cikiss1 小时前
微服务实战——平台属性
java·数据库·后端·微服务
weixin_464078071 小时前
C#串口温度读取
开发语言·c#
OEC小胖胖1 小时前
Spring Boot + MyBatis 项目中常用注解详解(万字长篇解读)
java·spring boot·后端·spring·mybatis·web
2401_857617622 小时前
SpringBoot校园资料平台:开发与部署指南
java·spring boot·后端
计算机学姐2 小时前
基于SpringBoot+Vue的在线投票系统
java·vue.js·spring boot·后端·学习·intellij-idea·mybatis
Yvemil73 小时前
MQ 架构设计原理与消息中间件详解(二)
开发语言·后端·ruby