Translated from Waqas Anwar 2021 year 5 month 4 Japanese articles 《Making HTTP Requests in Blazor Server Apps》 [1]
Blazor Server The application uses standard ASP.NET Core Applications , Execute... On the server .NET Code . stay Blazor Server In the application , We can be like ASP.NET Core Web In the application , Access any... In the same way .NET Library or server functions . One of these functions is , Use HTTP Client Instances to third parties Web API send out HTTP request . In this tutorial , I'll show you how to create HTTP Client Different methods of examples . in addition , I will also show you how to Blazor Server Use third parties in your application API To get and display data .
The third party Web API overview
We will develop a Blazor Server Applications , The application allows users to Blazor Enter the country code and year on the page component , Then we will call a third party API To get a list of public holidays in the specified country and year . The third party we use API yes Nager.Date[3], It's a global public holiday API.
This is a very simple API, You can easily in Postman Enter the following URL Test this API.
https://date.nager.at/api/v2/PublicHolidays/2021/CN
The API The response is JSON List of public holidays in format , As shown below :
from Blazor Sever Application start
stay Visual Studio 2019 Create a Blazor Server Applications , And create a new one called Models Folder . stay Models Add the following two model classes to the folder , To map the above Holidays API Request and response .
HolidayRequestModel.cs
public class HolidayRequestModel
{
public string CountryCode { get; set; }
public int Year { get; set; }
}
HolidayResponseModel.cs
public class HolidayResponseModel
{
public string Name { get; set; }
public string LocalName { get; set; }
public DateTime? Date { get; set; }
public string CountryCode { get; set; }
public bool Global { get; set; }
}
Next , stay Pages Create a new Razor Components HolidaysExplorer.razor And its code behind files HolidaysExplorer.razor.cs. If you want to know about Razor More knowledge of components and code behind files , You can read my article 《Blazor Getting started with components 》.
HolidaysExplorer.razor.cs
public partial class HolidaysExplorer
{
private HolidayRequestModel HolidaysModel = new HolidayRequestModel();
private List<HolidayResponseModel> Holidays = new List<HolidayResponseModel>();
[Inject]
protected IHolidaysApiService HolidaysApiService { get; set; }
private async Task HandleValidSubmit()
{
Holidays = await HolidaysApiService.GetHolidays(HolidaysModel);
}
}
HolidaysModel The fields are HolidayRequestModel An instance of a class , It will help us create a simple form to ask users for country code and year . The following code snippet shows how to use HolidaysModel Object created Blazor Forms , among HandleValidSubmit The method is to use Blazor Form Of OnValidSubmit Event configuration , This method will be called when the user submits the form .
<EditForm Model="@HolidaysModel" OnValidSubmit="@HandleValidSubmit" class="form-inline">
<label class="ml-2">Country Code:</label>
<InputText id="CountryCode" @bind-Value="HolidaysModel.CountryCode" class="form-control" />
<label class="ml-2">Year:</label>
<InputNumber id="Year" @bind-Value="HolidaysModel.Year" class="form-control" />
<button class="btn btn-primary ml-2" type="submit">Submit</button>
</EditForm>
Holidays The list is used to display information from third parties API Return vacation . We need to use a @foreach
Loop iterates over the returned vacation to generate a simple bootstrap form .
@if (Holidays.Count > 0)
{
<table class="table table-bordered table-striped table-sm">
<thead>
<tr>
<th>Date</th>
<th>Name</th>
<th>Local Name</th>
<th>Country Code</th>
<th>Global</th>
</tr>
</thead>
<tbody>
@foreach (var item in Holidays)
{
<tr>
<td>@item.Date.Value.ToShortDateString()</td>
<td>@item.Name</td>
<td>@item.LocalName</td>
<td>@item.CountryCode</td>
<td>@item.Global</td>
</tr>
}
</tbody>
</table>
}
HolidaysExplorer.razor The complete code of the view is as follows :
HolidaysExplorer.razor
@page "/"
<h3>Holidays Explorer</h3>
<br />
<EditForm Model="@HolidaysModel" OnValidSubmit="@HandleValidSubmit" class="form-inline">
<label class="ml-2">Country Code:</label>
<InputText id="CountryCode" @bind-Value="HolidaysModel.CountryCode" class="form-control" />
<label class="ml-2">Year:</label>
<InputNumber id="Year" @bind-Value="HolidaysModel.Year" class="form-control" />
<button class="btn btn-primary ml-2" type="submit">Submit</button>
</EditForm>
<br />
@if (Holidays.Count > 0)
{
<table class="table table-bordered table-striped table-sm">
<thead>
<tr>
<th>Date</th>
<th>Name</th>
<th>Local Name</th>
<th>Country Code</th>
<th>Global</th>
</tr>
</thead>
<tbody>
@foreach (var item in Holidays)
{
<tr>
<td>@item.Date.Value.ToShortDateString()</td>
<td>@item.Name</td>
<td>@item.LocalName</td>
<td>@item.CountryCode</td>
<td>@item.Global</td>
</tr>
}
</tbody>
</table>
}
At this point, if you run the application , You'll see a simple... That doesn't show any holidays HTML Forms . This is because of the method HandleValidSubmit It's empty. , We haven't called any API To get vacation data .
stay Blazor Server Used in applications IHttpClientFactory establish HttpClient
stay Blazor Server Used in applications HttpClient Ask a third party API There are many different ways , Let's start with a basic example , In this example, we use IHttpClientFactory
establish HttpClient
object .
Create one in the project Services Folder , And create the following IHolidaysApiService Interface . The interface has only one method GetHolidays, It uses HolidayRequestModel As a parameter and return HolidayResponseModel List of objects .
IHolidaysApiService.cs
public interface IHolidaysApiService
{
Task<List<HolidayResponseModel>> GetHolidays(HolidayRequestModel holidaysRequest);
}
Next , stay Services Create a HolidaysApiService class , Implement the above interface .
HolidaysApiService.cs
public class HolidaysApiService : IHolidaysApiService
{
private readonly IHttpClientFactory _clientFactory;
public HolidaysApiService(IHttpClientFactory clientFactory)
{
_clientFactory = clientFactory;
}
public async Task<List<HolidayResponseModel>> GetHolidays(HolidayRequestModel holidaysRequest)
{
var result = new List<HolidayResponseModel>();
var url = string.Format("https://date.nager.at/api/v2/PublicHolidays/{0}/{1}",
holidaysRequest.Year, holidaysRequest.CountryCode);
var request = new HttpRequestMessage(HttpMethod.Get, url);
request.Headers.Add("Accept", "application/vnd.github.v3+json");
var client = _clientFactory.CreateClient();
var response = await client.SendAsync(request);
if (response.IsSuccessStatusCode)
{
var stringResponse = await response.Content.ReadAsStringAsync();
result = JsonSerializer.Deserialize<List<HolidayResponseModel>>(stringResponse,
new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
}
else
{
result = Array.Empty<HolidayResponseModel>().ToList();
}
return result;
}
}
Above GetHolidays In the method , We first for the third party API Created a URL, And add the country code and year parameters to URL in .
var url = string.Format("https://date.nager.at/api/v2/PublicHolidays/{0}/{1}", holidaysRequest.Year, holidaysRequest.CountryCode);
Next , We created HttpRequestMessage Object and configure it to communicate to third parties API URL send out HTTP GET request .
var request = new HttpRequestMessage(HttpMethod.Get, url);
request.Headers.Add("Accept", "application/vnd.github.v3+json");
have access to Dependency injection (DI) Request one IHttpClientFactory, That's why we injected it into the constructor of the previous class . The following line of code uses IHttpClientFactory Created a HttpClient example .
var client = _clientFactory.CreateClient();
With HttpClient After object , We simply call its SendAsync Method to send a HTTP GET request .
var response = await client.SendAsync(request);
If API Successful call , We use the following line of code to read its response as a string .
var stringResponse = await response.Content.ReadAsStringAsync();
Last , We use JsonSerializer Class Deserialize Method to deserialize the response .
result = JsonSerializer.Deserialize<List<HolidayResponseModel>>(stringResponse,
new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
Before testing the application , We need to be in Startup.cs Register in the file HolidaysApiService service . We also need to call AddHttpClient Methods registration IHttpClientFactory.
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddSingleton<IHolidaysApiService, HolidaysApiService>();
services.AddHttpClient();
}
Run the application and provide any country code and year in the text box . Click on Submit The button will call our... In the background GetHolidays Method , Then you should see a list of public holidays as shown below .
stay Blazor Server Created in the application name HttpClient object
The above example applies to an existing application that you are refactoring , You want to do this without affecting the entire application , Use... In some methods IHttpClientFactory establish HttpClient The scene of the object . If you want to create a new application , Or you want to create HttpClient The way objects are centralized , Then you must use name HttpClient.
Here's how to create a named HTTP The benefits of the client :
- We can for each HttpClient name , And specify and when the application starts HttpClient All related configurations , Instead of distributing the configuration throughout the application .
- We can configure named... Only once HttpClient, And reuse it many times to call a specific API All of the providers API.
- According to the usage of these clients in different areas of the application , Configure the naming of multiple different configurations HttpClient object .
We can do it in Startup.cs Of documents ConfigureServices In the method , Use the previously used name AddHttpClient Method specifies a named HttpClient.
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddSingleton<IHolidaysApiService, HolidaysApiService>();
services.AddHttpClient("HolidaysApi", c =>
{
c.BaseAddress = new Uri("https://date.nager.at/");
c.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
});
}
We need to specify the name of the client ( for example HolidaysApi), We can also configure... As shown above BaseAddress、DefaultRequestHeaders And other properties .
Naming is configured HttpClient after , We can use the same CreateClient Method to create... Throughout the application HttpClient object , But this time we need to specify which named client we want to create ( for example HolidaysApi).
HolidaysApiService.cs
public class HolidaysApiService : IHolidaysApiService
{
private readonly IHttpClientFactory _clientFactory;
public HolidaysApiService(IHttpClientFactory clientFactory)
{
_clientFactory = clientFactory;
}
public async Task<List<HolidayResponseModel>> GetHolidays(HolidayRequestModel holidaysRequest)
{
var result = new List<HolidayResponseModel>();
var url = string.Format("api/v2/PublicHolidays/{0}/{1}",
holidaysRequest.Year, holidaysRequest.CountryCode);
var request = new HttpRequestMessage(HttpMethod.Get, url);
var client = _clientFactory.CreateClient("HolidaysApi");
var response = await client.SendAsync(request);
if (response.IsSuccessStatusCode)
{
var stringResponse = await response.Content.ReadAsStringAsync();
result = JsonSerializer.Deserialize<List<HolidayResponseModel>>(stringResponse,
new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
}
else
{
result = Array.Empty<HolidayResponseModel>().ToList();
}
return result;
}
}
We are CreateClient Method ( such as HolidaysApi) You have to be with us Startup.cs The names configured in the file are consistent . Every time you call CreateClient When the method is used , Will create a new HttpClient example .
in addition , We don't need to ask URL It is specified in API Host name , Because we are Startup.cs The base address has been specified in the file .
Run the application again and provide the country code and year values , You should see the following list of public holidays .
stay Blazor Server Created in the application Typification HttpClient object
Create and use HttpClient The third option for objects is to use typed clients . This client has the following benefits :
- They provide the same functionality as named clients , But you don't need to use a string as a key .
- They provide IntelliSense and compiler help when using the client .
- They provide a single storage unit to configure specific storage HttpClient And interact with it . for example , We can configure for Facebook API A type of a particular terminal HttpClient, And the HttpClient It can encapsulate all the logic required to use this particular terminal .
- They are related to dependency injection (DI) Use it together , You can inject... Where you need it .
To configure typed HTTPClient, We need to be in Startup.cs Use the same... In the file AddHttpClient Method to register it , But this time , We need to pass our service name HolidaysApiService As its type .
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddSingleton<IHolidaysApiService, HolidaysApiService>();
services.AddHttpClient<HolidaysApiService>();
}
In the code snippet above ,HTTP Clients and our services HolidaysApiService Will register as transient clients and services . This will allow us to pass... In the constructor of the service HttpClient, As shown in the following code snippet . Please note that ,HttpClient How it is exposed to serve public
Attribute .
HolidaysApiService.cs
public class HolidaysApiService : IHolidaysApiService
{
public HttpClient Client { get; }
public HolidaysApiService(HttpClient client)
{
client.BaseAddress = new Uri("https://date.nager.at/");
client.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
Client = client;
}
public async Task<List<HolidayResponseModel>> GetHolidays(HolidayRequestModel holidaysRequest)
{
var result = new List<HolidayResponseModel>();
var url = string.Format("api/v2/PublicHolidays/{0}/{1}",
holidaysRequest.Year, holidaysRequest.CountryCode);
var response = await Client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
var stringResponse = await response.Content.ReadAsStringAsync();
result = JsonSerializer.Deserialize<List<HolidayResponseModel>>(stringResponse,
new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
}
else
{
result = Array.Empty<HolidayResponseModel>().ToList();
}
return result;
}
}
The configuration of the typed client may not be specified in the constructor of the typed client , During the registration period Startup.cs Of documents ConfigureServices Method .
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddHttpClient<IHolidaysApiService, HolidaysApiService>(c =>
{
c.BaseAddress = new Uri("https://date.nager.at/");
c.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
});
}
If you use this method , You do not need to register your service separately . You can learn from ConfigureServices Method to delete the following line of code .
services.AddSingleton<IHolidaysApiService, HolidaysApiService>();
Can be HttpClient Objects are sealed in a typed client , Not publicly known as public
attribute . then , We can use this client in any method inside the service .
public class HolidaysApiService : IHolidaysApiService
{
private readonly HttpClient _httpClient;
public HolidaysApiService(HttpClient client)
{
_httpClient = client;
}
public async Task<List<HolidayResponseModel>> GetHolidays(HolidayRequestModel holidaysRequest)
{
var result = new List<HolidayResponseModel>();
var url = string.Format("api/v2/PublicHolidays/{0}/{1}",
holidaysRequest.Year, holidaysRequest.CountryCode);
var response = await _httpClient.GetAsync(url);
if (response.IsSuccessStatusCode)
{
var stringResponse = await response.Content.ReadAsStringAsync();
result = JsonSerializer.Deserialize<List<HolidayResponseModel>>(stringResponse,
new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
}
else
{
result = Array.Empty<HolidayResponseModel>().ToList();
}
return result;
}
}
Run the application again , And provide country code and year value , You should be able to see the following list of public holidays .
summary
In this paper , I introduced in Blazor Server Create and use... In your application HTTP Different technologies of the client . Most of the technologies mentioned here can also be found in ASP.NET Core Used in applications , because Blazor Server The application is built on ASP.NET Core On top of the infrastructure . In my next article 《Making HTTP Requests in Blazor WebAssembly Apps》 in , I will try to introduce HTTP The client is in Blazor WebAssembly Creation and use in applications .
Related reading :
- Blazor Server and WebAssembly Getting started with Applications
- Blazor Getting started with components
- Blazor Data binding Development Guide
- Blazor Event handling development guide
- Blazor Use... Between components EventCallback communicate
- Blazor Routing and Navigation Development Guide
- Blazor Template component development guide
- Blazor Server In the application HTTP request
author : Waqas Anwar
translate : Technical translation station
link : The original English text
https://www.ezzylearning.net/tutorial/making-http-requests-in-blazor-server-apps Making HTTP Requests in Blazor Server Apps ︎