从 ASP.NET Core Blazor 调用 Web APICall a web API from ASP.NET Core Blazor

本文内容

作者:Luke LathamDaniel RothJuan De la Cruz

重要

Blazor WebAssembly 为预览版状态

ASP.NET Core 3.0 支持 Blazor Server。Blazor WebAssembly 在 ASP.NET Core 3.1 中为预览版。

Blazor WebAssembly 应用使用预配置的 HttpClient 服务调用 Web API。使用 Blazor JSON 帮助程序或通过 HttpRequestMessage 撰写请求,其中可以包含 JavaScript Fetch API 选项。Blazor WebAssembly 应用中的 HttpClient 服务侧重于使请求返回源服务器。本主题中的指导仅适用于 Blazor WebAssembly 应用。

Blazor 服务器应用使用 HttpClient 实例(通常是使用 IHttpClientFactory 创建)调用 Web API。本主题中的指导不适用于 Blazor 服务器应用。开发 Blazor 服务器应用时,请按照 在 ASP.NET Core 中使用 IHttpClientFactory 发出 HTTP 请求 中的指导进行操作。

查看或下载示例代码如何下载)– 选择 BlazorWebAssemblySample 应用。

请查看 BlazorWebAssemblySample 示例应用中的以下组件:

  • 调用 Web API (Pages/CallWebAPI.razor )
  • HTTP 请求测试器 (Components/HTTPRequestTester.razor )

packagePackages

在项目文件中引用试验 Microsoft.AspNetCore.Blazor.HttpClient NuGet 包。Microsoft.AspNetCore.Blazor.HttpClient 基于 HttpClientSystem.Text.Json

若要使用稳定 API,请使用 Microsoft.AspNet.WebApi.Client 包,它使用 Newtonsoft.Json/Json.NETMicrosoft.AspNet.WebApi.Client 中使用稳定 API 并不提供本主题中所述的 JSON 帮助程序(它们对于试验 Microsoft.AspNetCore.Blazor.HttpClient 包是唯一的)。

HttpClient 和 JSON 帮助程序HttpClient and JSON helpers

在 Blazor WebAssembly 应用中,HttpClient 作为预配置服务提供,用于使请求返回源服务器。

默认情况下,Blazor 服务器应用不包含 HttpClient 服务。使用 HttpClient 工厂基础结构向应用提供 HttpClient

HttpClient 和 JSON 帮助程序还用于调用第三方 Web API 终结点。HttpClient 使用浏览器 Fetch API 来实现,受其限制制约,包括强制实施相同初始策略。

客户端的基址设置为原始服务器的地址。使用 @inject 指令插入 HttpClient 实例:

  1. @using System.Net.Http
  2. @inject HttpClient Http

在下面的示例中,Todo Web API 处理创建、读取、更新和删除 (CRUD) 操作。这些示例基于存储以下内容的 TodoItem 类:

  • ID(Idlong)– 项目的唯一 ID。
  • 名称(Namestring)– 项目的名称。
  • 状态(IsComplete``bool)– 指示 Todo 项是否已完成。
  1. private class TodoItem
  2. {
  3. public long Id { get; set; }
  4. public string Name { get; set; }
  5. public bool IsComplete { get; set; }
  6. }

JSON 帮助程序方法将请求发送到 URI(以下示例中的 Web API)并处理响应:

  • GetJsonAsync – 发送 HTTP GET 请求并分析 JSON 响应正文以创建对象。

在下面的代码中,_todoItems 由组件显示。当组件完成呈现 (OnInitializedAsync) 时,会触发 GetTodoItems 方法。有关完整的示例,请参阅示例应用。

  1. @using System.Net.Http
  2. @inject HttpClient Http
  3. @code {
  4. private TodoItem[] _todoItems;
  5. protected override async Task OnInitializedAsync() =>
  6. _todoItems = await Http.GetJsonAsync<TodoItem[]>("api/TodoItems");
  7. }
  • PostJsonAsync – 发送 HTTP POST 请求(包括 JSON 编码的内容),并分析 JSON 响应正文以创建对象。

在下面的代码中,_newItemName 由组件的绑定元素提供。通过选择 <button> 元素来触发 AddItem 方法。有关完整的示例,请参阅示例应用。

  1. @using System.Net.Http
  2. @inject HttpClient Http
  3. <input @bind="_newItemName" placeholder="New Todo Item" />
  4. <button @onclick="@AddItem">Add</button>
  5. @code {
  6. private string _newItemName;
  7. private async Task AddItem()
  8. {
  9. var addItem = new TodoItem { Name = _newItemName, IsComplete = false };
  10. await Http.PostJsonAsync("api/TodoItems", addItem);
  11. }
  12. }
  • PutJsonAsync – 发送 HTTP PUT 请求(包括 JSON 编码的内容)。

在下面的代码中,NameIsCompleted_editItem 值由组件的绑定元素提供。当在 UI 的另一个部分中选择项并调用 EditItem 时,会设置项的 Id。通过选择 Save <button> 元素来触发 SaveItem 方法。有关完整的示例,请参阅示例应用。

  1. @using System.Net.Http
  2. @inject HttpClient Http
  3. <input type="checkbox" @bind="_editItem.IsComplete" />
  4. <input @bind="_editItem.Name" />
  5. <button @onclick="@SaveItem">Save</button>
  6. @code {
  7. private TodoItem _editItem = new TodoItem();
  8. private void EditItem(long id)
  9. {
  10. var editItem = _todoItems.Single(i => i.Id == id);
  11. _editItem = new TodoItem { Id = editItem.Id, Name = editItem.Name,
  12. IsComplete = editItem.IsComplete };
  13. }
  14. private async Task SaveItem() =>
  15. await Http.PutJsonAsync($"api/TodoItems/{_editItem.Id}, _editItem);
  16. }

System.Net.Http 包括用于发送 HTTP 请求和接收 HTTP 响应的附加扩展方法。HttpClient.DeleteAsync 用于将 HTTP DELETE 请求发送到 Web API。

在下面的代码中,Delete <button> 元素调用 DeleteItem 方法。绑定 <input> 元素提供要删除的项的 id有关完整的示例,请参阅示例应用。

  1. @using System.Net.Http
  2. @inject HttpClient Http
  3. <input @bind="_id" />
  4. <button @onclick="@DeleteItem">Delete</button>
  5. @code {
  6. private long _id;
  7. private async Task DeleteItem() =>
  8. await Http.DeleteAsync($"api/TodoItems/{_id}");
  9. }

跨域资源共享 (CORS)Cross-origin resource sharing (CORS)

浏览器安全可防止网页向不同域(而不是向网页提供服务的域)进行请求。此限制称为同域策略 。同域策略可防止恶意站点从另一站点读取敏感数据。若要从浏览器向具有不同源的终结点进行请求,终结点 必须启用跨域资源共享 (CORS)

Blazor WebAssembly 示例应用 (BlazorWebAssemblySample) 演示如何在调用 Web API 组件 (Pages/CallWebAPI.razor ) 中使用 CORS。

若要允许其他站点对应用进行跨域资源共享 (CORS) 请求,请参阅 启用 ASP.NET Core 中的跨域请求 (CORS)

具有 Fetch API 请求选项的 HttpClient 和 HttpRequestMessageHttpClient and HttpRequestMessage with Fetch API request options

在 Blazor WebAssembly 应用中的 WebAssembly 上运行时,可使用 HttpClientHttpRequestMessage 自定义请求。例如,可以指定请求 URI、HTTP 方法以及任何所需的请求标头。

  1. @using System.Net.Http
  2. @using System.Net.Http.Headers
  3. @inject HttpClient Http
  4. @code {
  5. private async Task PostRequest()
  6. {
  7. Http.DefaultRequestHeaders.Authorization =
  8. new AuthenticationHeaderValue("Bearer", "{OAUTH TOKEN}");
  9. var requestMessage = new HttpRequestMessage()
  10. {
  11. Method = new HttpMethod("POST"),
  12. RequestUri = new Uri("https://localhost:10000/api/TodoItems"),
  13. Content =
  14. new StringContent(
  15. @"{""name"":""A New Todo Item"",""isComplete"":false}")
  16. };
  17. requestMessage.Content.Headers.ContentType =
  18. new System.Net.Http.Headers.MediaTypeHeaderValue(
  19. "application/json");
  20. requestMessage.Content.Headers.TryAddWithoutValidation(
  21. "x-custom-header", "value");
  22. var response = await Http.SendAsync(requestMessage);
  23. var responseStatusCode = response.StatusCode;
  24. var responseBody = await response.Content.ReadAsStringAsync();
  25. }
  26. }

有关 Fetch API 选项的详细信息,请参阅 MDN Web 文档:WindowOrWorkerGlobalScope.fetch():Parameters

在 CORS 请求中发送凭据(授权 cookie/标头)时,CORS 策略必须允许使用 Authorization 标头。

以下策略包括的配置用于:

  • 请求来源(http://localhost:5000https://localhost:5001)。
  • Any 方法(谓词)。
  • Content-TypeAuthorization 标头。若要允许使用自定义标头(例如 x-custom-header),请在调用 WithHeaders 时列出标头。
  • 由客户端 JavaScript 代码设置的凭据(credentials 属性设置为 include)。
  1. app.UseCors(policy =>
  2. policy.WithOrigins("http://localhost:5000", "https://localhost:5001")
  3. .AllowAnyMethod()
  4. .WithHeaders(HeaderNames.ContentType, HeaderNames.Authorization, "x-custom-header")
  5. .AllowCredentials());

有关详细信息,请参阅 启用 ASP.NET Core 中的跨域请求 (CORS) 和示例应用的 HTTP 请求测试器组件 (Components/HTTPRequestTester.razor )。

其他资源Additional resources