A simple graphical explanation of Blazor's effect on the web development landscape.

HttpClient in Blazor

This post was most recently updated on October 27th, 2019.

Reading Time: 3 minutes.

Blazor is a new (ish) framework for building web UIs with C#. It either uses SignalR to manage connections between your client-side and server-side code, or even compiles directly to WebAssembly, in both cases cutting out the need to write any pesky JavaScript yourself – pretty neat, if you ask me!

However, developing your web apps with Blazor is a bit different from using ASP.NET MVC, for example. Other people have written great introductions to the tech, so I’ll stick to the problem at hand: Using HttpClient with Blazor (Server).

Description

With Blazor, a lot of your code runs serverside, and you’re using serverside dependencies. One example of this is HTTP queries, to which you need the class HttpClient. However, not all of the “classic” web server stack you might’ve grown to expect is available without configuration – and HttpClient is probably the most obvious dependency that’ll require an additional step to get it up and running.


Solution

Prior to Blazor (and .NET Core) preview 9, the code below was a simple way to get access to the HttpClient via @inject – basically, add the code below into your StartUp.cs’s ConfigureServices method:

if (!services.Any(x => x.ServiceType == typeof(HttpClient)))
{
	// Setup HttpClient for server side in a client side compatible fashion
	services.AddScoped<HttpClient>(s =>
	{
		// Creating the URI helper needs to wait until the JS Runtime is initialized, so defer it.
		var uriHelper = s.GetRequiredService<IUriHelper>();
		return new HttpClient
		{
			BaseAddress = new Uri(uriHelper.GetBaseUri())
		};
	});
}

The way this works in your code elsewhere, no matter which version of ASP.NET Core you’re on, is this:

@inject HttpClient Http
 
...
 
@code {
 
 string yourAPIUrl = "https://yourepicapisite.azurewebsites.net/api/getdata";
 
 protected override async Task OnInitializedAsync()
 {
  // do something with your HttpClient - in this case, GET data from your custom API...
  var t = Http.GetAsync(yourAPIUrl);
 
  ...
 
 }
}

Preview 9 changed the configuration part a bit, though, as UriHelper is not used anymore, but rather replaced with NavigationManager. It’s essentially the same thing in this case – so I just replaced the requested service to be that.

Below, you can see how you can request and use it when configuring the HttpClient:

// Server Side Blazor doesn't register HttpClient by default
if (!services.Any(x => x.ServiceType == typeof(HttpClient)))
{
	// Setup HttpClient for server side in a client side compatible fashion
	services.AddScoped<HttpClient>(s =>
	{
		// Creating the URI helper needs to wait until the JS Runtime is initialized, so defer it.
		var uriHelper = s.GetRequiredService<NavigationManager>();
		return new HttpClient
		{
			BaseAddress = new Uri(uriHelper.BaseUri)
		};
	});
}

Pretty easy and straightforward!

NavMan & UriHelper madness

A quick detour here – UriHelper injection and name has changed back and forth a few times. This post below should explain that a bit more:

Just another bit of documentation that’s tough to maintain :)

References

mm

3
Leave a Reply

avatar
5000
2 Comment threads
1 Thread replies
2 Followers
 
Most reacted comment
Hottest comment thread
2 Comment authors
mmGerard Recent comment authors
  Subscribe  
Notify of
Gerard
Guest
Gerard

Antti, I have been struggling and searching since the release of 3.0 with trying to get “HttpClient.GetJsonAsync” to compile. All I had to do was use “HttpClient.GetAsync”. It is my opinion that the changes in this release were not properly explained.

THANK YOU!

Gerard
Guest
Gerard

One comment Antti,

In your example you may want to show the following in order to consume the result:

var t = Http.GetAsync(yourAPIUrl);
t.EnsureSuccessStatusCode();
string responseBody = await t.Content.ReadAsStringAsync();