Отправка http-запросов

HttpClient в проекте Blazor Server

Последнее обновление: 30.11.2023

Для отправки запросов по протоколу HTTP приложение Blazor, как и в общем приложение на .NET, использует класс HtppClient. Рассмотрим, как отправлять подобные запросы к серверу. Для этого определим следующий проект:

Отправка запросов к серверу из приложения на Blazor в ASP.NET Core

В проекте Blazor экземпляр HttpClient обычно создается с помощью фабрики IHttpClientFactory, как это обычно делается вообще в проекте ASP.NET Core. Для этого в файле Program.cs определим следующий код:

using BlazorApp.Components;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();


builder.Services.AddHttpClient();  // добавляем фабрику HttpClient

var app = builder.Build();

app.UseAntiforgery();

// на запрос по пути "/time" возвращаем время
app.MapGet("/time", () => DateTime.Now.ToShortTimeString());

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();


app.Run();

Для получения HttpClient добавляем сервис IHttpClientFactory:

builder.Services.AddHttpClient();

Для тестирования сервиса добавляем конечную точку, которая по запросу по пути "/time" возвращает текущее время:

app.MapGet("/time", () => DateTime.Now.ToShortTimeString());

Компонент App в данном случае будет корневым и будет обращаться к компоненту Home:

@page "/"

<!DOCTYPE html>
<html>
<head>
    <title>METANIT.COM</title>
    <meta charset="utf-8" />
</head>
<body>
    <Home />
    <script src="_framework/blazor.web.js"></script>
</body>
</html>

А для тестирования http-запросов определим следующий компонент Home:

@using Microsoft.AspNetCore.Components.Web

@rendermode RenderMode.InteractiveServer
@inject IHttpClientFactory ClientFactory

<h2>@time</h2>
<button @onclick="Submit">Click</button>

@code {
    string? time;
    async Task Submit()
    {
        HttpClient httpClient = ClientFactory.CreateClient();
        var response = await httpClient.GetAsync("https://localhost:7066/time");
        time = await response.Content.ReadAsStringAsync();
    }
}

Прежде всего получаем сервис IHttpClientFactory с помощью директивы @inject:

@inject IHttpClientFactory ClientFactory

Для тестирования в компоненте определена кнопка, по нажатию на которую срабатывает метод Submit. В этом методе с помощью фабрики IHttpClientFactory создаем объект HttpClient

HttpClient httpClient = ClientFactory.CreateClient();

Выполняем запрос по пути "/time":

var response = await httpClient.GetAsync("https://localhost:7066/time");

Стоит отметить, что здесь указывается полный адрес. В моем случае адрес текущего приложения - "https://localhost:7066/time".

Поскольку сервер возвращает клиенту время в виде строки, с помощью метода ReadAsStringAsync() считываем ответ сервера в строку и передаем ее переменной time

time = await response.Content.ReadAsStringAsync();
Отправка запросов с помощью HttpClient в приложении Blazor Server на C#

В остальном работа с HttpClient будет идти также как и в принципе в .NET.

Отправка данных

Отправка запросов и получение ответов с помощью HttpClient в приложении Blazor будет идти также, как и в целом в .NET - Отправка запросов с помощью HttpClient. Поэтому рассмотрим лишь один сценарий - отправку данных в POST-запросе. Пусть файл Program.cs выглядит следующим образом:

using BlazorApp.Components;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();


builder.Services.AddHttpClient();  // добавляем фабрику HttpClient

var app = builder.Build();

app.UseAntiforgery();

app.MapPost("/user", (Person user) =>
{
    // если длина имени меньше 3 или больше 20 символов
    if (user.Name.Length < 3 || user.Name.Length > 20)
        return Results.BadRequest(new { details = "Имя должно иметь не меньше 3 и не больше 20 символов" });
    // если возраст меньше 1 или больше 110
    if (user.Age < 1 || user.Age > 110)
        return Results.BadRequest(new { details = "Некорректный возраст" });
    // если все нормально, устанавливаем id для нового пользователя
    user.Id = Guid.NewGuid().ToString();
    // посылаем объект в виде json
    return Results.Json(user);
});

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();


app.Run();


public class Person
{
    public string Id { get; set; } = "";
    public string Name { get; set; } = "";
    public int Age { get; set; }
}

Здесь предполагается, что клиент в POST-запросе по пути "/user" будет отправлять объект Person. При получении данных валидируем их (имя должно иметь от 3 до 20 символов, а возраст должен быть в диапазоне от 1 до 110). Если они не соответствуют некоторым ограничениям, то посылаем ошибку 400 и объект json с сообщением об ошибке:

if(user.Name.Length < 3 || user.Name.Length > 20) 
    return Results.BadRequest(new {details="Имя должно иметь не меньше 3 и не больше 20 символов" });
if (user.Age < 1 || user.Age > 110)
    return Results.BadRequest(new {details = "Некорректный возраст" });

Если данные корректны, то устанавиваем у объекта Person свойство Id и посылаем его в формате JSON обратно клиенту:

user.Id = Guid.NewGuid().ToString();
return Results.Json(user);

Для взаимодействия с этим веб-приложением в компоненте Home определим следующий код:

@using Microsoft.AspNetCore.Components.Web
@using System.Net.Http.Json

@rendermode RenderMode.InteractiveServer
@inject IHttpClientFactory ClientFactory

<div style="color:red;">@message</div>

<div>
    <p>
        Имя:<br />
        <input @bind-value="person.Name" />
    </p>
    <p>
        Возраст:<br />
        <input type="number" @bind-value="person.Age" />
    </p>
    <button @onclick="Submit">Click</button>
</div>

@code {
    string? message;
    Person person = new();
    async Task Submit()
    {
        message = "";
        HttpClient httpClient = ClientFactory.CreateClient();
        var response = await httpClient.PostAsJsonAsync("https://localhost:7066/user", person);
        if (response.IsSuccessStatusCode)
        {
            var newPerson = await response.Content.ReadFromJsonAsync<Person>();
            if (newPerson != null) message = $"Создан объект Person с id = {newPerson.Id}";
        }
        else
        {
            var error = await response.Content.ReadFromJsonAsync<Error>();
            if (error != null) message = error.Details;
        }
    }
    class Error
    {
        public string Details { get; set; } = "";
    }
    class Person
    {
        public string Id { get; set; } = "";
        public string Name { get; set; } = "";
        public int Age { get; set; }
    }
}

Здесь определена форма с двумя полями ввода, которые привязаны к свойствам Name и Age объекта Person. По нажатию на кнопку срабатывает метод Submit, который в POST-запросе в виде кода json отправляет приложению ASP.NET Core объект Person.

При успешном запросе (если сервер возвращает статусный код 2хх) получаем отправленный сервером объект Person с установленным Id и этот Id выводим в сообщении:

if (response.IsSuccessStatusCode)
{
    var newPerson = await response.Content.ReadFromJsonAsync<Person> ();
    if (newPerson != null) message = $"Создан объект Person с id = {newPerson.Id}";
}

Если же сервер возвратил ошибку (в нашем случае ошибку 400 при некорректности данных), получаем сообщение об ошибке в объект Error, и затем также выводим сообщение об ошибке на страницу:

else
{
    var error = await response.Content.ReadFromJsonAsync<Error>();
    if (error != null) message = error.Details;
}

Пример работы:

Создание проекта ASP.NET Web API для тестирования приложения Blazor на C#
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850