100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
C#

HttpClient and Calling APIs

Learn how to configure and use HttpClient in Blazor Server and WebAssembly to call REST APIs safely and efficiently.

State & ServicesIntermediate10 min readJul 10, 2026
Analogies

HttpClient in Blazor Server vs. WebAssembly

Blazor components call external APIs through HttpClient, but the two hosting models configure it very differently: Blazor WebAssembly runs entirely in the browser, so its HttpClient is constrained by the browser's fetch API and CORS policy and can only reach origins the target server allows; Blazor Server runs on the server, so its HttpClient calls happen server-side with no CORS restriction, but every request adds latency to the SignalR round trip that's already rendering the UI.

🏏

Cricket analogy: A player fielding at the boundary can only throw the ball within reach of teammates on the field, just as a WASM HttpClient is boundary-restricted by CORS to origins the server explicitly allows.

Configuring HttpClient with AddHttpClient

The recommended way to configure HttpClient is AddHttpClient<TClient>() from Microsoft.Extensions.Http, which registers a typed client, wires up IHttpClientFactory under the hood to pool and recycle underlying HttpMessageHandler instances, and lets you configure a BaseAddress, default headers, and Polly-based retry or circuit-breaker policies in one place. Injecting the typed client directly into a component, rather than a raw HttpClient, keeps API-calling logic testable and avoids the socket-exhaustion problems that come from constructing HttpClient instances by hand.

🏏

Cricket analogy: A franchise's dedicated bowling coach configures every net session with the right run-up markers and drills in one place rather than each bowler improvising, similar to AddHttpClient centralizing BaseAddress and headers in Program.cs.

Handling Responses, Errors, and Cancellation

Because network calls can fail or hang, production code should check response.IsSuccessStatusCode before deserializing, wrap the call so a non-2xx response produces a meaningful error rather than an unhandled exception from ReadFromJsonAsync, and pass a CancellationToken tied to the component's lifetime, typically from a CancellationTokenSource created in OnInitializedAsync and cancelled in Dispose, so an in-flight request doesn't try to update a component the user has already navigated away from.

🏏

Cricket analogy: An umpire always checks the ball's condition before declaring it fit for play rather than assuming it's fine, just as code should check IsSuccessStatusCode before trusting and deserializing a response body.

csharp
builder.Services.AddHttpClient<WeatherApiClient>(client =>
{
    client.BaseAddress = new Uri("https://api.weather.example/");
    client.DefaultRequestHeaders.Add("Accept", "application/json");
})
.AddTransientHttpErrorPolicy(policy => policy.WaitAndRetryAsync(3, _ => TimeSpan.FromSeconds(1)));
csharp
@inject WeatherApiClient WeatherApi
@implements IDisposable

@code {
    private CancellationTokenSource _cts = new();
    private WeatherForecast[]? forecasts;

    protected override async Task OnInitializedAsync()
    {
        var response = await WeatherApi.Http.GetAsync("forecast", _cts.Token);
        if (response.IsSuccessStatusCode)
        {
            forecasts = await response.Content.ReadFromJsonAsync<WeatherForecast[]>(cancellationToken: _cts.Token);
        }
    }

    public void Dispose() => _cts.Cancel();
}

IHttpClientFactory, wired up automatically by AddHttpClient, pools and recycles the underlying HttpMessageHandler instances behind the scenes, which avoids both the socket-exhaustion problems of a HttpClient created per-request and the stale-DNS problems of a single HttpClient held forever as a static field.

In Blazor WebAssembly, a raw HttpClient's requests are subject to the browser's CORS policy; if the target API doesn't return the right Access-Control-Allow-Origin headers, the call fails in the browser console with a CORS error even though the same endpoint works fine when called from Blazor Server or Postman.

  • Blazor WASM's HttpClient runs in the browser and is subject to CORS; Blazor Server's runs server-side and isn't
  • AddHttpClient<TClient>() registers a typed client backed by IHttpClientFactory, avoiding manual HttpClient lifecycle bugs
  • Configure BaseAddress, default headers, and Polly retry/circuit-breaker policies once in Program.cs
  • Always check response.IsSuccessStatusCode before deserializing to avoid unhandled exceptions on error responses
  • Pass a CancellationToken tied to the component's lifetime to cancel in-flight requests on navigation away
  • Avoid constructing HttpClient with 'new' directly in components; inject a typed client instead
  • Blazor Server API calls add latency on top of the existing SignalR round trip

Practice what you learned

Was this page helpful?

Topics covered

#BlazorStudyNotes#MicrosoftTechnologies#HttpClientAndCallingAPIs#HttpClient#Calling#APIs#Blazor#StudyNotes#SkillVeris#ExamPrep