HttpClient in Blazor Webassembly
How to make http calls to send and receive server-side from a blazor webassembly app. A Blazor Webassembly application runs on the client-side in the browser. What if the application needs server-side data. Well, it can communicate with the server over http.
In Blazor we use a class called HttpClient
to make http calls to send and receive data from an API. In both the hosting models, that is Blazor WebAssembly and Blazor Server we use this same HttpClient
class.
There are several approcahes to use this HttpClient class. A word of caution though, if not implemented correctly it can lead to problems like socket exhaustion
or failing to handle DNS changes
. Going through all these different approaches is too time consuming and only makes it more confusing.
So to keep it simple, let's use the recommended approach. For real world enterprise apps, the recommended approach is to use IHttpClientFactory
. This approach works with both the hosting models, that is, Blazor Webassembly and Blazor Server. It's the same code that we use in both the hosting models which means it's easy to convert a Blazor Server app to a Blazor Webassembly app and vice-versa. It also offers several benefits like providing a central location for configuring HttpClient instances, it also avoids the problems like failing to handle DNS changes and socket exhaustion. The following are the steps to use IHttpClientFactory.
Step 1 : Implement a wrapper service
For separation of concerns implement a wrapper service that uses the HttpClient instance to call server side REST API to send and receive data.
If you are wondering why a separate wrapper service? Well, for separation of concerns. We do not want our Blazor components to be doing too many things. If a component needs server side data, it injects this wrapper service and calls it. So, our natural first step is to implement a wrapper service that calls server side REST API using the built-in HttpClient class.
Create Services
folder in BlazorProject.Client
project and the following 2 files (IEmployeeService.cs and EmployeeService.cs)
IEmployeeService.cs
using BlazorProject.Shared;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace BlazorProject.Client.Services
{
public interface IEmployeeService
{
Task<IEnumerable<Employee>> Search(string name, Gender? gender);
Task<IEnumerable<Employee>> GetEmployees();
Task<Employee> GetEmployee(int employeeId);
Task<Employee> GetEmployeeByEmail(string email);
Task<Employee> AddEmployee(Employee employee);
Task<Employee> UpdateEmployee(Employee employee);
Task DeleteEmployee(int employeeId);
}
}
EmployeeService.cs
We only provided implementation for GetEmployees()
method. We will implement the rest of the methods in our upcoming videos.
using BlazorProject.Shared;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;
namespace BlazorProject.Client.Services
{
public class EmployeeService : IEmployeeService
{
private readonly HttpClient httpClient;
public EmployeeService(HttpClient httpClient)
{
this.httpClient = httpClient;
}
public async Task<IEnumerable<Employee>> GetEmployees()
{
return await httpClient.GetFromJsonAsync<IEnumerable<Employee>>("api/employees");
}
public Task<Employee> AddEmployee(Employee employee)
{
throw new NotImplementedException();
}
public Task DeleteEmployee(int employeeId)
{
throw new NotImplementedException();
}
public Task<Employee> GetEmployee(int employeeId)
{
throw new NotImplementedException();
}
public Task<Employee> GetEmployeeByEmail(string email)
{
throw new NotImplementedException();
}
public Task<IEnumerable<Employee>> Search(string name, Gender? gender)
{
throw new NotImplementedException();
}
public Task<Employee> UpdateEmployee(Employee employee)
{
throw new NotImplementedException();
}
}
}
GetFromJsonAsync method in .NET
GetFromJsonAsync
sends an HTTP GET request and parses the JSON response body to create an object. This method is in System.Net.Http.Json
namespace. In addition to GetFromJsonAsync()
, we also have PostAsJsonAsync()
, PutAsJsonAsync()
and DeleteAsync()
Step 2 : Install Microsoft.Extensions.Http nuget package
Includes the AddHttpClient
extension method for IServiceCollection
.
Step 3 : Configure IHttpClientFactory and related services
In the Main()
method in Program.cs
file, add IHttpClientFactory
and related services
builder.Services.AddHttpClient<IEmployeeService, EmployeeService>(client =>
{
client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress);
});
Since we are using the IHttpClientFactory
to configure HttpClient
we no longer need the following code.
//builder.Services.AddScoped(sp =>
//new HttpClient
//{
// BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)
//});
Step 4 : Inject wrapper service in Blazor components
public List<Employee> Employees { get; set; }
[Inject]
public IEmployeeService EmployeeService { get; set; }
protected override async Task OnInitializedAsync()
{
Employees = (await EmployeeService.GetEmployees()).ToList();
}
© 2020 Pragimtech. All Rights Reserved.