从 ASP.NET Core 调用 web API Blazor
作者: Luke Latham、 Daniel Roth和Juan De la Cruz
重要
Blazor WebAssembly 为预览版状态
ASP.NET Core 3.0 支持 Blazor Server 。 Blazor WebAssembly 在 ASP.NET Core 3.1 中为预览版。
Blazor WebAssembly应用使用预先配置的 HttpClient
服务来调用 web api。 撰写请求,其中可以包含 JavaScript提取 API选项,使用 Blazor JSON 帮助程序或 HttpRequestMessage。 Blazor WebAssembly apps 中的 HttpClient
服务的重点是将请求发回源服务器。 本主题中的指导仅适用于 Blazor WebAssembly 应用。
Blazor Server apps 使用 HttpClient 实例来调用 web api,通常是使用 IHttpClientFactory创建的。 本主题中的指南与 Blazor 服务器应用无关。 开发 Blazor 服务器应用时,请按照 在 ASP.NET Core 中使用 IHttpClientFactory 发出 HTTP 请求中的指南进行操作。
查看或下载示例代码(如何下载) – 选择BlazorWebAssemblySample应用。
请参阅BlazorWebAssemblySample示例应用中的以下组件:
- 调用 Web API (Pages/CallWebAPI)
- HTTP 请求测试器(组件/HTTPRequestTester)
包
引用实验性BlazorAspNetCore。项目文件中的 HttpClient NuGet 包。 Microsoft.AspNetCore.Blazor.HttpClient
基于 HttpClient
和system.object。
若要使用稳定的 API,请使用WebApi包,其中使用newtonsoft.json/Json.NET。 在 Microsoft.AspNet.WebApi.Client
中使用稳定 API 并不提供本主题中所述的 JSON 帮助程序,这对于实验性 Microsoft.AspNetCore.Blazor.HttpClient
包是唯一的。
HttpClient 和 JSON 帮助器
在 Blazor WebAssembly 应用中, HttpClient作为预配置服务提供,用于向源服务器发送请求。
默认情况下,Blazor Server 应用不包括 HttpClient
服务。 使用HttpClient 工厂基础结构向应用提供 HttpClient
。
HttpClient
和 JSON 帮助程序还用于调用第三方 web API 终结点。 HttpClient
是使用浏览器提取 API实现的,并且受到其限制,包括强制实施相同的源策略。
客户端的基址设置为源服务器的地址。 使用 @inject
指令插入 HttpClient
实例:
@using System.Net.Http @inject HttpClient Http
在下面的示例中,Todo web API 处理创建、读取、更新和删除(CRUD)操作。 这些示例基于存储以下内容的 TodoItem
类:
- ID (
Id
、long
) – 项的唯一 ID。 - 名称(
Name
、string
) – 项的名称。 - 状态(
IsComplete
、bool
) – 指示 Todo 项是否已完成。
private class TodoItem { public long Id { get; set; } public string Name { get; set; } public bool IsComplete { get; set; } }
JSON helper 方法将请求发送到 URI (以下示例中的 web API)并处理响应:
GetJsonAsync
– 发送 HTTP GET 请求并分析 JSON 响应正文来创建对象。在下面的代码中,
_todoItems
由组件显示。 当组件完成呈现(OnInitializedAsync)时,将触发GetTodoItems
方法。 有关完整示例,请参阅示例应用。@using System.Net.Http @inject HttpClient Http @code { private TodoItem[] _todoItems; protected override async Task OnInitializedAsync() => _todoItems = await Http.GetJsonAsync<TodoItem[]>("api/TodoItems"); }
PostJsonAsync
– 发送 HTTP POST 请求(包括 JSON 编码的内容),并分析 JSON 响应正文来创建对象。在下面的代码中,
_newItemName
由组件的绑定元素提供。 通过选择<button>
元素触发AddItem
方法。 有关完整示例,请参阅示例应用。@using System.Net.Http @inject HttpClient Http <input @bind="_newItemName" placeholder="New Todo Item" /> <button @onclick="@AddItem">Add</button> @code { private string _newItemName; private async Task AddItem() { var addItem = new TodoItem { Name = _newItemName, IsComplete = false }; await Http.PostJsonAsync("api/TodoItems", addItem); } }
PutJsonAsync
– 发送 HTTP PUT 请求,包括 JSON 编码的内容。在下面的代码中,
Name
和IsCompleted
的_editItem
值由组件的绑定元素提供。 当在 UI 的另一部分中选择项并调用EditItem
时,将设置该项的Id
。 通过选择 Save<button>
元素触发SaveItem
方法。 有关完整示例,请参阅示例应用。@using System.Net.Http @inject HttpClient Http <input type="checkbox" @bind="_editItem.IsComplete" /> <input @bind="_editItem.Name" /> <button @onclick="@SaveItem">Save</button> @code { private TodoItem _editItem = new TodoItem(); private void EditItem(long id) { var editItem = _todoItems.Single(i => i.Id == id); _editItem = new TodoItem { Id = editItem.Id, Name = editItem.Name, IsComplete = editItem.IsComplete }; } private async Task SaveItem() => await Http.PutJsonAsync($"api/TodoItems/{_editItem.Id}, _editItem); }
System.Net.Http 包括用于发送 HTTP 请求和接收 HTTP 响应的附加扩展方法。 HttpClient. DeleteAsync用于将 HTTP DELETE 请求发送到 web API。
在下面的代码中,Delete <button>
元素调用 DeleteItem
方法。 绑定 <input>
元素提供要删除的项的 id
。 有关完整示例,请参阅示例应用。
@using System.Net.Http @inject HttpClient Http <input @bind="_id" /> <button @onclick="@DeleteItem">Delete</button> @code { private long _id; private async Task DeleteItem() => await Http.DeleteAsync($"api/TodoItems/{_id}"); }
跨域资源共享(CORS)
浏览器安全性可防止网页向其他域发出请求,而不是提供给网页的域。 此限制称为相同源策略。 同一源策略可防止恶意站点读取另一个站点中的敏感数据。 若要将浏览器请求发送到具有不同源的终结点,终结点必须启用跨域资源共享(CORS)。
Blazor WebAssembly 示例应用(BlazorWebAssemblySample)演示了如何在调用 Web API 组件(Pages/CallWebAPI)中使用 CORS。
若要允许其他站点对应用进行跨域资源共享(CORS)请求,请参阅 启用 ASP.NET Core 中的跨域请求 (CORS)。
带有 Fetch API 请求选项的 HttpClient 和 HttpRequestMessage
在 Blazor WebAssembly 应用程序的 WebAssembly 上运行时,使用HttpClient和 HttpRequestMessage 自定义请求。 例如,可以指定请求 URI、HTTP 方法以及任何所需的请求标头。
@using System.Net.Http @using System.Net.Http.Headers @inject HttpClient Http @code { private async Task PostRequest() { Http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "{OAUTH TOKEN}"); var requestMessage = new HttpRequestMessage() { Method = new HttpMethod("POST"), RequestUri = new Uri("https://localhost:10000/api/TodoItems"), Content = new StringContent( @"{""name"":""A New Todo Item"",""isComplete"":false}") }; requestMessage.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue( "application/json"); requestMessage.Content.Headers.TryAddWithoutValidation( "x-custom-header", "value"); var response = await Http.SendAsync(requestMessage); var responseStatusCode = response.StatusCode; var responseBody = await response.Content.ReadAsStringAsync(); } }
有关获取 API 选项的详细信息,请参阅MDN web 文档: WindowOrWorkerGlobalScope ():P arameters。
在 CORS 请求上发送凭据(授权 cookie/标头)时,CORS 策略必须允许 Authorization
标头。
以下策略包括的配置:
- 请求来源(
http://localhost:5000
、https://localhost:5001
)。 - 任何方法(谓词)。
Content-Type
和Authorization
标头。 若要允许自定义标头(例如x-custom-header
),请在调用 WithHeaders时列出该标头。- 由客户端 JavaScript 代码(
credentials
属性设置为include
)设置的凭据。
app.UseCors(policy => policy.WithOrigins("http://localhost:5000", "https://localhost:5001") .AllowAnyMethod() .WithHeaders(HeaderNames.ContentType, HeaderNames.Authorization, "x-custom-header") .AllowCredentials());
有关详细信息,请参阅 启用 ASP.NET Core 中的跨域请求 (CORS) 和示例应用的 HTTP 请求测试器组件(组件/HTTPRequestTester)。