current position:Home>HTTP requests in the blazor server application

HTTP requests in the blazor server application

2021-08-27 01:22:46 Technical translation

Translated from Waqas Anwar 2021 year 5 month 4 Japanese articles 《Making HTTP Requests in Blazor Server Apps》 [1]

Making-HTTP-Requests-in-Blazor-Server-Apps

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 .

Download the source code [2]

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.

Nager.Date-World-Wide-Public-Holidays-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 :

World-Wide-Public-Holidays-API-in-Postman

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 .

Simple-Form-using-Blazor-Form-Component

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 .

Making-HTTP-Requests-in-Blazor-Server-Apps-1

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 :

  1. 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 .
  2. We can configure named... Only once HttpClient, And reuse it many times to call a specific API All of the providers API.
  3. 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 BaseAddressDefaultRequestHeaders 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 .

Making-HTTP-Requests-in-Blazor-Server-Apps-1

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 :

  1. They provide the same functionality as named clients , But you don't need to use a string as a key .
  2. They provide IntelliSense and compiler help when using the client .
  3. 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 .
  4. 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 .

Using-HTTP-Client-to-Call-Third-Party-APIs-in-Blazor

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 :

author : Waqas Anwar
translate : Technical translation station
link : The original English text


  1. https://www.ezzylearning.net/tutorial/making-http-requests-in-blazor-server-apps Making HTTP Requests in Blazor Server Apps

  2. https://github.com/ezzylearning/BlazorServerWebAPIsDemo

  3. https://date.nager.at/

copyright notice
author[Technical translation],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2021/08/20210827012240086H.html

Random recommended