在 Blazor Web 应用中执行 HTTP 操作
本单元将介绍如何使用 IHttpClientFactory 来处理 HTTP 客户端的创建和处置,以及如何使用该客户端在 ASP.NET Blazor Web 应用中执行 REST 操作。 本单元中使用的代码示例基于与 API 交互,该 API 可管理存储在数据库中的水果列表。 本单元中的信息基于在 Razor 应用中使用代码隐藏文件。
以下代码表示代码示例中引用的数据模型:
public class FruitModel
{
// An id assigned by the database
public int id { get; set; }
// The name of the fruit
public string? name { get; set; }
// A boolean to indicate if the fruit is in stock
public bool instock { get; set; }
}
在应用中注册 IHttpClientFactory
若要在应用中添加 IHttpClientFactory,请在 Program.cs 文件中注册 AddHttpClient。 下面的代码示例使用命名客户端类型,设置 REST 操作中使用的 API 的基址,并在本单元的其余部分中引用。
// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
// Add IHttpClientFactory to the container and set the name of the factory
// to "FruitAPI". The base address for API requests is also set.
builder.Services.AddHttpClient("FruitAPI", httpClient =>
{
httpClient.BaseAddress = new Uri("http://localhost:5050/");
});
var app = builder.Build();
确定 API 中的操作要求
在使用 API 执行操作之前,需要确定 API 的预期内容:
- API 终结点:确定操作的终结点,以便根据需要正确调整存储在基址中的 URI。
- 数据要求:确定操作返回/预期的是可枚举的还是只有一条数据。
注意
本单元其余部分中的代码示例假定每个 HTTP 操作在解决方案中的单独页上进行处理。
执行 GET 操作
GET 操作不应发送正文,而是用于(如方法名称所示)从资源检索数据。 如果给定 HttpClient 和 URI,可使用 HttpClient.GetAsync 方法执行 HTTP GET 操作。 例如,如果要在 Razor Page 应用的主页 (Home.razor) 上创建一个表,以显示 GET 操作的结果,则需要将以下内容添加到代码隐藏文件 (Home.razor.cs):
- 使用依赖项注入将
IHttpClientFactory添加到页面模型。 - 创建
HttpClient的实例 - 执行
GET操作并将结果反序列化到数据模型中。
以下代码示例演示如何执行 GET 操作。 请务必阅读代码中的注释。
public partial class Home : ComponentBase
{
// IHttpClientFactory set using dependency injection
[Inject]
public required IHttpClientFactory HttpClientFactory { get; set; }
[Inject]
private NavigationManager? NavigationManager { get; set; }
/* Add the data model, an array is expected as a response */
private IEnumerable<FruitModel>? _fruitList;
// Begin GET operation when the component is initialized
protected override async Task OnInitializedAsync()
{
// Create the HTTP client using the FruitAPI named factory
var httpClient = HttpClientFactory.CreateClient("FruitAPI");
// Perform the GET request and store the response. The parameter
// in GetAsync specifies the endpoint in the API
using HttpResponseMessage response = await httpClient.GetAsync("/fruits");
// If the request is successful deserialize the results into the data model
if (response.IsSuccessStatusCode)
{
using var contentStream = await response.Content.ReadAsStreamAsync();
_fruitList = await JsonSerializer.DeserializeAsync<IEnumerable<FruitModel>>(contentStream);
}
else
{
// If the request is unsuccessful, log the error message
Console.WriteLine($"Failed to load fruit list. Status code: {response.StatusCode}");
}
}
}
执行 POST 操作
POST 操作应发送正文,并用于向资源添加数据。 如果给定 HttpClient 和 URI,可使用 HttpClient.PostAsync 方法执行 HTTP POST 操作。 如果要使用表单向主页的数据中添加项,则需要:
- 使用依赖项注入将
IHttpClientFactory添加到页面模型。 - 使用
EditForm或EditContext模型将数据绑定到表单。 - 使用
JsonSerializer.Serialize方法序列化要添加的数据。 - 创建
HttpClient的实例 - 执行
POST操作。
注意
遵循每个 REST 操作的单独页面的项目模型,在 Add.razor 页中执行 POST 操作,代码示例位于 Add.razor.cs 代码隐藏文件中。
以下代码示例演示如何执行 POST 操作。 请务必阅读代码中的注释。
namespace FruitWebApp.Components.Pages;
public partial class Add : ComponentBase
{
// IHttpClientFactory set using dependency injection
[Inject]
public required IHttpClientFactory HttpClientFactory { get; set; }
// NavigationManager set using dependency injection
[Inject]
private NavigationManager? NavigationManager { get; set; }
// Add the data model and bind the form data to it
[SupplyParameterFromForm]
private FruitModel? _fruitList { get; set; }
protected override void OnInitialized() => _fruitList ??= new();
// Begin POST operation code
private async Task Submit()
{
// Serialize the information to be added to the database
var jsonContent = new StringContent(JsonSerializer.Serialize(_fruitList),
Encoding.UTF8,
"application/json");
// Create the HTTP client using the FruitAPI named factory
var httpClient = HttpClientFactory.CreateClient("FruitAPI");
// Execute the POST request and store the response. The response will contain the new record's ID
using HttpResponseMessage response = await httpClient.PostAsync("/fruits", jsonContent);
// Check if the operation was successful, and navigate to the home page if it was
if (response.IsSuccessStatusCode)
{
NavigationManager?.NavigateTo("/");
}
else
{
Console.WriteLine("Failed to add fruit. Status code: {response.StatusCode}");
}
}
}
执行其他 REST 操作
其他操作(如 PUT 和 DELETE )遵循前面所示的相同模型。 下表定义了常见的 REST 操作以及关联的 HttpClient 方法:
| 请求 | 方法 | 定义 |
|---|---|---|
| GET | HttpClient.GetAsync |
检索资源 |
| POST | HttpClient.PostAsync |
创建新资源 |
| PUT | HttpClient.PutAsync |
更新现有资源,或创建新资源(如果不存在) |
| DELETE | HttpClient.DeleteAsync |
删除资源 |
| PATCH | HttpClient.PatchAsync |
部分更新现有资源 |