Как отправить запрос из приложения Blazor Hybrid к ASP.NET Core Web API, используя протокол HTTP?

На данный момент у меня есть приложение Blazor Hybrid .NET MAUI (клиент) для работы на смартфоне/планшете, которое сохраняет в локальную базу данных SQLite данные о местоположении пользователя, фотографии и т.д. А также приложение ASP.NET Core Web API, которое должно принимать от клиентов собранные данные, обрабатывать их и формировать единую базу данных. При попытке отправить данные с клиента Blazor Hybrid в приложение ASP.NET Core Web API я столкнулся с тем, что клиент постоянно выдает ошибку «Connection failure». Разберемся с тем, как отправить запрос из приложения Blazor Hybrid к ASP.NET Core Web API, используя протокол HTTP.

Сразу стоит отметить, что предложенный ниже вариант работы клиента и сервера по протоколу HTTP не является безопасным и используется в целях отладки.

Причина ошибки Connection failure в Blazor Hybrid

Итак, следуя документации Microsoft по Blazor, для использования HttpClient мы должны зарегистрировать сервис в нашем приложении и, используя директиву Razor @inject запросить зависимость в необходимом нам компоненте. В приложении Blazor Hybrid эта рекомендация может выглядеть следующим образом:

в файле MauiProgram.cs регистрируем новый сервис:

var builder = MauiApp.CreateBuilder();
builder
    .UseMauiApp<App>()
    .ConfigureFonts(fonts =>
    {
        fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
    });

//добавляем сервис HttpClient
builder.Services.AddScoped(sp => new HttpClient());

//здесь регистрация других зависимостей, настройка приложения и т.д.

return builder.Build();
}

Теперь запросим сервис в любом компоненте Razor, например

@page "/tethering"

@inject HttpClient client 

<Heading Size="HeadingSize.Is5">Связь с сервером</Heading>

<Button Clicked="Connect">Передать данные</Button>

@code {
    private int port = 1000;
    private string ipAddress = "192.168.143.133";

    public async Task Connect()
    {
        string address = $"http://{ipAddress}:{port}/api/controller";
        var orgs = await Context.Organizations.ToListAsync();
        foreach (var org in orgs)
        {
            await client.PostAsJsonAsync(address, org);
        }
    }
}

здесь мы пытаемся отправить POST-запрос по адресу http://192.168.143.133:1000/api/controller, передав в теле запроса некий объект Organization. Сервер ASP.NET Core Web API содержит необходимый контроллер, в приложении настроен в том числе и CORS, поэтому, по логике, такой запрос должен без проблем пройти. Однако, при попытке отправить запрос мы получаем ошибку:

Если посмотреть подробности этой ошибки в отладчике, то мы увидим:

Дело в том, что, начиная с версии Android 9 Pie по умолчанию для работы с ресурсами в сети необходимо использовать протокол HTTPS. Чтобы настроить работу приложения Android 9 и выше на работу с HTTP необходимо дополнительно настроить параметры безопасности сетевого подключения приложения (об этом ниже).

Вернемся к нашему приложению и попробуем отправить запрос по https:

@page "/tethering"

@inject HttpClient client 

<Heading Size="HeadingSize.Is5">Связь с сервером</Heading>

<Button Clicked="Connect">Передать данные</Button>

@code {
    private int port = 1000;
    private string ipAddress = "192.168.143.133";

    public async Task Connect()
    {
        string address = $"https://{ipAddress}:{port}/api/controller";//меняем протокол на https
        var orgs = await Context.Organizations.ToListAsync();
        foreach (var org in orgs)
        {
            await client.PostAsJsonAsync(address, org);
        }
    }
}

И здесь мы снова получим ту же ошибку «Connection failure» в консоли, однако причина этой ошибки будет иная:

Более того, после решения и этой ошибки я получил третью — недостоверный сертификат. В общем, для того, чтобы максимально быстро начать отладку приложений, я решил полностью отказаться от использования https и настроить работу как клиента, так и сервера на работу только с http.

Настройка приложения Blazor Hybrid для работы с HTTP в Android

По умолчанию, в Android 9 и выше мы должны настроить параметры безопасности сетевого подключения приложения, чтобы использовать протокол http. Сделать это можно двумя способами. Первый самый простой — добавить атрибут android:usesCleartextTraffic="true" в элемент application манифеста приложения:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application android:usesCleartextTraffic="true"....> </application>
...
</manifest>

Второй способ немного сложнее, однако позволяет более тонко настраивать параметры безопасности. Для этого, создадим в папке Platforms/Android/Resources папку xml в которой разместим файл network_security_config.xml:

со следующим содержимым:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true" />
</network-security-config>

и теперь изменим манифест приложения следующим образом:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application android:networkSecurityConfig="@xml/network_security_config" ...></application>
        здесь прочие настройки манифеста 
</manifest>

Результат будет тот же. что и в первом случае — приложение сможет отправлять запросы по http. Теперь нам необходимо обеспечить работу с http на сервере.

Настройка приложения ASP.NET Core Web API

Опять же, по умолчанию, приложение ASP.NET Core Web API перенаправляет все запросы с http на https. Для этого конвейер обработки запросов в приложении использует следующий компонент middleware:

app.UseHttpsRedirection();

Просто закомментируйте эту строку, чтобы отключить автоматическое перенаправление на https. Теперь, что клиент, что сервер будут работать по протоколу http без каких-либо ограничений и перенаправлений и отладка приложения будет проходить без каких-либо проблем:

Итого

Здесь мы настроили работу как приложения Blazor Hybrid в Android, так и ASP.NET Core Web API на работу с протоколом HTTPS. Как сказано в самом начале — такой подход небезопасен в готовом приложении и его рекомендуется использовать только для целей отладки.

Подписаться
Уведомить о
guest
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии