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
接下来,将控制台应用程序配置为使用适用于 .NET 的 StackExchange.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托管在HTTP和HTTPS终结点中。
创建项目时,将为 HTTP 选择 5000 到 5300 端口,为 HTTPS 选择 7000 到 7300 端口。 通过编辑项目的 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 内部。
-
打开
CsharpWebAPI.http文件。此文件已预配置了
@ContosoPizza_HostAddress变量和调用/weatherforecast/的 GET 命令,该命令接受application/json。 -
选择
GET上方的"发送请求"命令,该命令会将请求发送到正在运行的服务。调用此命令将打开一个响应窗口,其输出与我们在浏览器中看到的以下内容类似:
jsonHTTP/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的 HTTPGET请求将执行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")]属性指定的单个控制器操作。 此属性将HTTPGET请求路由到public IEnumerable<WeatherForecast> Get()方法。 如你所见,在上一个练习中,向https://localhost:{PORT}/weatherforecast发出请求会导致返回天气预报结果。本模块的后面部分会介绍其他常见操作与执行
CRUD操作(GET、PUT、POST、DELETE)的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 API:dotnet run
5. 使用.http 文件测试控制器
- 打开
CsharpWebAPI.http - 添加新的
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 操作的工作原理。 让我们来详细了解一下 POST、PUT 和 DELETE 操作。
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 可让客户端知道请求是否成功,并提供新创建的披萨的 ID。 IActionResult 使用标准 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返回类型未知。BadRequest、NotFound和NoContent方法分别返回BadRequestResult、NotFoundResult和NoContentResult类型。
由于控制器批注通过
[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返回类型未知。NotFound和NoContent方法分别返回NotFoundResult和NoContentResult类型。 - 查询内存中缓存以获取与所提供的
id参数匹配的披萨。
在继续操作之前,请记得保存 Controllers/PizzaController.cs 文件。
运行以下命令,生成并启动 Web API:dotnet 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