overview
Blazor WASM apps call web APIs using a preconfigured HttpClient service which is focused on HttpClient service configurations manually for requests to other web APIs.
- Documentation: https://learn.microsoft.com/en-us/aspnet/core/blazor/call-web-api?view=aspnetcore-7.0&pivots=webassembly
sending patch requests
If sending HTTP PATCH requests, there are additional considerations beyond those listed in these notes.
See:
https://learn.microsoft.com/en-us/aspnet/core/blazor/call-web-api?view=aspnetcore-7.0&pivots=webassembly#patch-as-json-patchasjsonasync
Using the Preconfigured HttpClient
Add the HttpClient service to the DI container:
Program.csbuilder.Services.AddScoped(sp => new HttpClient { // The client's base address is set to the originating server's address: BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });Inject required services:
SomeComponent.razor@using System.Net.Http <!-- For HttpClientJsonExtensions: --> @using System.Net.Http.Json @inject HttpClient HttpSend requests from the component in the
OnInitializedAsync()method after the component has finished initializing:SomeComponent.razor@code { private TodoItem[]? todoItems; protected override async Task OnInitializedAsync() => todoItems = await Http.GetFromJsonAsync<TodoItem[]>("api/TodoItems"); }
Using the IHttpClientFactory
Instead of injecting a preconfigured HttpClient, IHttpClientFactory can be used instead, similar to
how it is used in other .NET apps.
Both named and typed clients are supported.
named client example
Program.cs:
builder.Services.AddHttpClient("NAMED_CLIENT_NAME", client =>
client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress));
SomeComponent.razor
@inject IHttpClientFactory ClientFactory
<!-- ... -->
@code {
// ...
protected override async Task OnInitializedAsync()
{
var client = ClientFactory.CreateClient("NAMED_CLIENT_NAME");
result = await client.GetFromJsonAsync<SomeModel[]>("SomeModel");
}
}
typed client example
- Add
Microsoft.Extensions.Httpto the app:dotnet add package Microsoft.Extensions.Http - Create the typed client:
SomeHttpClient.cspublic class SomeHttpClient { private readonly HttpClient http; private SomeModel[]? results; public SomeHttpClient(HttpClient http) { this.http = http; } public async Task<SomeModel[]> GetResultsAsync() { results = await http.GetFromJsonAsync<SomeModel[]>("/api/endpoint"); return results ?? Array.Empty<SomeModel>(); } } - Use the typed client:
SomeComponent.razor@inject SomeHttpClient Http <!-- ... -->@code { private SomeModel[]? results; protected override async Task OnInitializedAsync() { results = await Http.GetResultsAsync(); } }
fetch api request options
Blazor WASM’s implementation of HttpClient uses Fetch API. Fetch API can be configured with request-specific options via HttpRequestMessage extension methods:
| Extension Method | Use to… |
|---|---|
SetBrowserRequestCache | |
SetBrowserRequestCredentials | …include credentials in a cross-origin request |
SetBrowserRequestIntegrity | |
SetBrowserRequestMode | |
SetBrowserResponseStreamingEnabled | …enable support for response streaming |
Additional options can be set via the generic SetBrowserRequestOption extension method.
Cross-Origin Resource Sharing (CORS)
Browser security restricts a web page from making requests to a different domain than the one that served the web page. This is called the same-origin policy.
Adjust the names and ports of WithOrigins as needed for the app:Program.cs
// ...
app.UseCors(policy => policy
.WithOrigins("http://localhost:5000", "https://localhost:5001")
.AllowAnyMethod()
.WithHeaders(HeaderNames.ContentType);
// ...
See also: https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-7.0
testing a web api
Blazor framework’s reference source has HttpClient test assets:
https://github.com/dotnet/aspnetcore/tree/main/src/Components/test/testassets/BasicTestApp/HttpClientTest