翻譯自 Waqas Anwar 2021年5月13日的文章 《Making HTTP Requests in Blazor WebAssembly Apps》 [1]

在我的前篇文章《Blazor Server 應用程式中進行 HTTP 請求》中,我介紹了在 Blazor Server 應用程式中進行 HTTP 請求的相關技術,在 Blazor Server App 中您可以訪問所有的 .NET 類庫和元件。但如果您建立的是 Blazor WebAssembly 應用程式,那麼您的程式碼將在客戶端的瀏覽器沙箱中執行,您的選擇在某種程度上會受到限制。在本教程中,我將向您展示如何在 Blazor WebAssembly 應用程式進行 HTTP 請求。

Blazor WebAssembly 應用程式中的 HttpClient 概述

Blazor WebAssembly 應用程式使用預置的 HttpClient 服務呼叫 Web API。這個預置的 HttpClient 是使用瀏覽器的 Fetch API[2] 實現的,會有一些限制。HttpClient 還可以使用 Blazor JSON 幫助程式或 HttpRequestMessage 物件進行 API 呼叫。預設情況下,您只能向同源伺服器傳送 API 呼叫請求,不過如果第三方 API 支援跨域資源共享(CORS)的話,您也可以呼叫其他伺服器上的 API。

名稱空間 System.Net.Http.Json 為使用 System.Text.Json 執行自動序列化和反序列化的 HttpClient 提供了擴充套件方法。這些擴充套件方法將請求傳送到一個 Web API URI 並處理相應的響應。常用的方法有:

  • GetFromJsonAsync:傳送 HTTP GET 請求,並將 JSON 響應正文解析成一個物件。
  • PostAsJsonAsync:將 POST 請求傳送到指定的 URI,並在請求正文中載有序列化為 JSON 的 value
  • PutAsJsonAsync:傳送 HTTP PUT 請求,其中包含 JSON 編碼的內容。

要理解如何將這些方法與 HttpClient 一起使用,我們需要建立兩個專案。第一個專案是一個 Web API 專案,它向客戶端公開一個 Web API。第二個專案是 Blazor WebAssembly 應用程式,它向第一個專案中建立的 Web API 傳送 HTTP 請求。

實現一個 ASP.NET Core Web API

在本節中,我們將實現一個支援跨域資源共享 (CORS) 的 Web API,以便 Blazor WebAssembly 應用程式可以呼叫此 API。在 Visual Studio 2019 中建立一個新的 Web API 專案 BlazorClientWebAPI。我們將建立一個簡單的 API 來返回產品列表,所以首先要在專案中建立一個 Models 資料夾,並在其中新增如下的 Product 類。

Product.cs

public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}

接下來,建立一個 Controllers 資料夾並在其中新增下面的 ProductsController。該控制器簡單地從 GetProducts 方法返回一些模擬的產品資料。

ProductsController.cs

[Route("api/[controller]")]
[ApiController]
public class ProductsController : ControllerBase
{
[HttpGet]
public IActionResult GetProducts()
{
var products = new List<Product>()
{
new Product()
{
Id = 1,
Name = "Wireless Mouse",
Price = 29.99m
},
new Product()
{
Id = 2,
Name = "HP Headphone",
Price = 79.99m
},
new Product()
{
Id = 3,
Name = "Sony Keyboard",
Price = 119.99m
}
}; return Ok(products);
}
}

現在如果您執行該專案,並嘗試在瀏覽器中使用 URI api/products 訪問該 API,您應該能看到以 JSON 格式返回的產品資料。

在 ASP.NET Core Web API 中啟用 CORS

預設情況下,瀏覽器安全性不允許一個網頁向除提供該網頁的域之外的其他域傳送請求。這種約束稱之為同源策略。如果我們希望 Blazor WebAssembly 應用程式或其他客戶端應用程式使用上述 Web API,那麼我們必須啟用跨域資源共享 (CORS)。開啟 Startup.cs 檔案,並在 ConfigureServices 方法中呼叫 AddCors 方法。

public void ConfigureServices(IServiceCollection services)
{
services.AddCors(policy =>
{
policy.AddPolicy("CorsPolicy", opt => opt
.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod());
}); services.AddControllers();
}

同時,在 Startup.cs 檔案的 Configure 方法中新增以下程式碼行。

app.UseCors("CorsPolicy");

有關使用 ASP.NET Core 應用程式的 CORS 的詳細資訊,請參閱 《Enable Cross-Origin Requests (CORS) in ASP.NET Core》[3]

實現 Blazor WebAssembly 應用程式

在建立上述 Web API 專案的同一解決方案中新增一個新的 Blazor WebAssembly 應用程式專案 BlazorClientWebAPIsDemo

我們需要確保的第一件事是,在專案檔案中有 System.Net.Http.Json 的引用。如果沒有,那麼您可以新增該引用。

<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="5.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="5.0.1" PrivateAssets="all" />
<PackageReference Include="System.Net.Http.Json" Version="5.0.0" />
</ItemGroup>
</Project>

接下來,我們需要在 Program.cs 檔案中配置 HttpClient 服務。確保提供了要從 Blazor WebAssembly 應用程式呼叫的 Web API 的基地址。

Program.cs

public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app"); builder.Services.AddScoped(sp => new HttpClient
{
BaseAddress = new Uri("http://localhost:5000/api/")
}); await builder.Build().RunAsync();
}

為了使用產品 API,我們在 Pages 資料夾中建立一個 Products.razor 元件。該檢視非常簡單,因為它只是迭代產品列表並使用簡單的 HTML 表格來顯示它們。

Products.razor

@page "/products"

<h1>Products</h1>

@if (products == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Price</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in products)
{
<tr>
<td>@forecast.Id</td>
<td>@forecast.Name</td>
<td>@forecast.Price</td>
</tr>
}
</tbody>
</table>
}

建立一個程式碼隱藏檔案 Products.razor.cs,並將配置的 HttpClient 例項作為私有成員注入到該類中。最後,使用 GetFromJsonAsync 方法呼叫產品 API。

Products.razor.cs

public partial class Products
{
private List<Product> products; [Inject]
private HttpClient Http { get; set; } protected override async Task OnInitializedAsync()
{
products = await Http.GetFromJsonAsync<List<Product>>("products");
}
}

您還需要在 Blazor WebAssembly 專案中建立一個 Product 類的本地副本,以將產品 API 的結果反序列化為產品物件列表。

public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}

執行該專案,您將看到從後端 Web API 載入了產品的頁面。

相關閱讀:

作者 : Waqas Anwar

翻譯 : 技術譯站

連結 : 英文原文


  1. https://www.ezzylearning.net/tutorial/making-http-requests-in-blazor-webassembly-apps Making HTTP Requests in Blazor WebAssembly Apps

  2. https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API Fetch API

  3. https://docs.microsoft.com/zh-cn/aspnet/core/security/cors