This tutorial will focus on explaining what Blazor is as well as the difference between Blazor server and Blazor web Assembly. Furthermore, it will also explain how to make an API request in Blazor server.
What is Blazor?
Firstly, Blazor is a framework which is used to build UI applications using the .NET framework, C# and HTML. Blazor uses “Components” to hold the code which can be placed inside of other components in order to compartmentalise the code, allowing for smaller more succinct files which can be used as Nuget packages or external libraries. Benefits of Blazor include being able to write C# code that is inline with HTML instead of JavaScript, also, you have the opportunity to take advantage of the wide array of Nuget packages that are on offer, in addition to, the ability to use the scalability and performance benefits that .NET offers.
For this tutorial I will be using a Blazor server application.
Firstly, we will need to create a Blazor project, so open up your editor of choice (mine is Rider) and choose to create a Blazor server application. On Rider there are 2 sections on the left of the wizard when picking a project to create. One for “.NET Core” and a second for “.NET”, I have chosen the “ASP .NET Core Web Application” option and then from the “Type” dropdown pick Blazor Server.
You will be greeted by a whole host of files including “Program.cs” and “Startup.cs” which will be explained shortly.
API Introduction
The API I will be using for this tutorial is a fake data api which can be found at this url.
The endpoint we will be calling is this “https://jsonplaceholder.typicode.com/posts” and it will retrieve the properties “userId”, “id”, “title” and “body”.
What is Startup.cs and Program.cs?
The Startup file is only present in a Blazor Server application and is not found in a Blazor WebAssembly app. However, the program file is present in both projects. The startup file is used to initialise services that are required to run the app, by default the startup file has a service “WeatherForecastService”.
You will notice “WeatherForecastService” uses “services.AddSingleton” which is one of three lifetimes that can be attributed to a service. The purpose of “AddSingleton” is so dependency injection only creates one instance of the service during startup.cs and will reuse this object throughout all calls to the service in the system.
Other than “AddSingleton” there is also “Scoped” and “Transient”.
Transient — Whenever a component or API controller retrieves an instance of a service that is added via the use of “transient” from the service container it receives a new instance of the service.
Scoped — Services with a scoped lifetime are once per request and recreates the services on each HTTP request, however, the scoped lifetime is not supported across SignalR circuit messages. Scoped services are not reconstructed when traversing across components on the client. However, the services are reconstructed when the user closes the browser window, closes a tab or user refreshes the browser.
The Program.cs file is the entry point for the Blazor server app which sets up host-level services such as logging and dependency injection. Blazor WebAssembly Program.cs file also does something similar, however, the Blazor WebAssembly Program.cs file does not create a HTTP server because the app is executed in the browser, whereas, Blazor server is ran on the server.
Starting to write some code
Right, time for some code, so our first call of action is to add a HttpClient service to the Startup.cs file as the Blazor server app does not include the service by default. A HttpClient will allow us to send http requests and receive responses in order to manipulate them to show it to the user.
So open the Startup.cs file and within the ConfigureServices method enter the below code underneath the “AddSingleton<WeatherForecastService>();”
services.AddHttpClient();
Once you have completed this right click the project name and look for an option named (or similar) “Add”, within this menu there are further options. I am using Rider so I need to click “Blazor Component”.
Name the file something like “BlazorWebApiCall”. The first thing we will do is give the component a url that can be reached within the application. To do this navigate to the top line of the file and enter the below.
@page "/call-web-api"
This means that when we run the application we can either enter “call-web-api” (excluding the quotation marks) in the web browser after the default url or create a button to navigate to the page href.
Furthermore, for this tutorial we won’t be using any Nuget packages such as Newtonsoft but instead stick with the built-in namespaces.
In addition, what we now need to do is include in our file the extensions we require. These are System.Text.Json and System.Text.Json.Serialization
The System.Text.Json namespace gives us the ability to process JSON and serialize/deserialize objects to and from JSON.
Meanwhile, we also need to inject a dependency into this file as well and this dependency is the IHttpClientFactory dependency, IHttpClientFactory can be used if you wish to manage multiple instances of HttpClient for this tutorial we will only use one instance but for a lot of use cases multiple API calls will need to be made per component.
@inject IHttpClientFactory ClientFactory
When you created your page the Blazor component should have created an “@code” space for you to enter C# code in.
Within these curly brackets enter the below class.
public class FakeData
{
public int userId { get; set; }
public int id { get; set; }
public string body { get; set; }
public string title { get; set; }
}
The class above matches the data and its properties that will be returned from the API so we will be able to deserialize the returned response from the api into an object of this class.
Since the response from the API will be returning more than 1 record we need to create a list variable of the FakeData type.
public List<FakeData> fakeDataList = new List<FakeData>();
Below this variable use the Blazor lifecycle method “protected override async Task OnInitializedAsync” to make the request to the API. This lifecycle method is ran the first time that the component is rendered so is an ideal time to call APIs in order to instantly show the data we need to show to the user.
protected override async Task OnInitializedAsync()
{}
Inside of “OnInitializedAsync” create a variable called “apiRequest” and set it equal to a “HttpRequestMessage”. The first parameter of “HttpRequestMessage” is the method type i.e. GET, DELETE and the second parameter is the url we want to request.
var request = new HttpRequestMessage(HttpMethod.Get, "https://jsonplaceholder.typicode.com/posts");
We now need to create a variable called “client” which creates an instance of HttpClient.
var client = ClientFactory.CreateClient();
After we create the HttpClient instance we need to send the request and then contain the response of the request in a variable with the return type of this variable being “HttpResponseMessage” and we do this with the below code.
var response = await client.SendAsync(request);
Afterwards we can perform a check on the “response” variable to ensure that the request was performed successfully and if so we can begin to read the response stream, this is useful for being able to gracefully handle errors on the UI side, as we could put an else statement after the “if” to show an error message to the user to indicate the request did not complete successfully.
if (response.IsSuccessStatusCode)
{}
Inside of this “if” we will now create a variable that contains the APIs response content as a stream of data.
await using var responseStream = await response.Content.ReadAsStreamAsync();
After this we will set the list variable equal to the “responseStream” variable that has been deserialized asynchronously into the type “List<FakeData>”
fakeDataList = await JsonSerializer.DeserializeAsync<List<FakeData>>(responseStream);
We have now finished the majority of the C# code and have retrieved the API data, we can now look at using this data to show to the user in a pretty way.
So now outside of the “@code” block use the “table” html tag and a class of “table table-striped”
<table class="table table-striped"></table>
Afterwards we now need to add the required headers of the table which will be equal to the properties of the data returned from the API.
<thead>
<tr>
<th>User id</th>
<th>id</th>
<th>Title</th>
<th>Body</th>
</tr>
</thead>
After “thead” we now need to add “tbody” to contain the main content of the table. Inside of the “tbody” we need to loop over the “fakeDataList” with a “element” variable. Inside of this loop write a “tr” with “td” tags inside of it so when each item is looped over a new row is created on the table with the necessary data with “@element” used to access the properties within the “FakeData” class
@foreach (var element in fakeDataList)
{
<tr>
<td>@element.userId</td>
<td>@element.id</td>
<td>@element.title</td>
<td>@element.body</td>
</tr>
}
Now enter “</tbody>” outside of the for loop and give your project a run.
In the address bar enter “/call-web-api” after the initial url and hit enter, you should see something like the below on your screen with the API response within the HTML table.
It has been a very long time since I have created an article (I think I have said that multiple times ha) but it is nice to be back and I hope people find this article beneficial, if you think I can do anything better then let me know in the responses and I will try to incorporate it into my future articles.
Thanks again!
See my blog — https://simplyreact.uk/