Sam
Sam

Reputation: 30334

Create and use HttpClient in a .NET MAUI app

Do we create/use an HttpClient in a .NET MAUI app, the same way we do, say, in a web or API app? Specifically, I add my HttpClient's to my app in Program.cs using IHttpFactory -- see below:

builder.Services.AddHttpClient("NamedClient1", config =>
{
    var url = currentState == "production"
        ? "https://my-production-url"
        : "https://sandbox-url";
    config.BaseAddress = new Uri(url);
});

I understand the idea with .NET MAUI is to standardize the way we handle things. When I tried adding the line builder.Services in my .NET MAUI app, IntelliSense does not suggest AddHttpClient though.

Upvotes: 10

Views: 20079

Answers (4)

Athanor
Athanor

Reputation: 46

I am using .NET 8 and developing a .NET MAUI Blazor Hybrid app which connects with my ASP.NET API

What our uncle Bill suggests (and works great) is to create an API Service:

Create your service class:

public class APIService : IAPIService
 {
     HttpClient _httpClient;
     JsonSerializerOptions _jsonSerializerOptions;
     Uri _baseURI;
     public APIService()
     {
         _httpClient = new HttpClient();
         _jsonSerializerOptions = new JsonSerializerOptions
         {
             PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
             WriteIndented = true,
         };
         _baseURI = new Uri("https://localhost:7148");
     }

     public async Task<bool> POSTCredentialsAsync(LoginCommand command)
     {
         var response = await _httpClient.PostAsJsonAsync(_baseURI + "/login", command);
         if (response.IsSuccessStatusCode)
         {
             return true;
         }
         return false;
     }

     public async Task<bool> POSTRegistrationAsync(RegisterMarket command)
     {
         var response = await _httpClient.PostAsJsonAsync(_baseURI + "/register", command);
         if (response.IsSuccessStatusCode)
         {
             return true;
         }
         return false;
     }
 }

like that above.

A Interface:

  internal interface IAPIService
  {
      public Task<bool> POSTCredentialsAsync(LoginCommand command);
      public Task<bool> POSTRegistrationAsync(RegisterMarket command);
  }

Lastly, in MauiProgram.cs

  builder.Services.AddScoped<IAPIService, APIService>();

Works really well in my apps

And you can handle the responses in another source file

Hope it helps

In blazor you can just use @inject HttpClient, but I don't like it because, as said, you'll have to handle the exceptions in the page source code, if you use that function path, it will turn redundant not to write a service class Thanks in advance

Microsoft oficial reference: https://learn.microsoft.com/en-us/dotnet/maui/data-cloud/rest?view=net-maui-9.0

Upvotes: 0

Matias Masso
Matias Masso

Reputation: 2000

Use as follows for .Net6 and .Net7:

    builder.Services.AddScoped(sp => new HttpClient { });

Upvotes: 6

gamzeml
gamzeml

Reputation: 1

Temperature.xaml.cs

using System.Diagnostics.Metrics;
using System.Text.Json;
using System.Xml.Serialization;

namespace TPMaui3.Views;

public partial class vTemperature : ContentPage
{
    public vTemperature()
    {
        InitializeComponent();
    }

    private void AfficheTemperature(object sender, EventArgs e)
    {
        LireTemperature();
    }

    private async void LireTemperature()
    {
        Uri uri = new("http://meteorestsrvmobile.lab3il.fr/RestServiceMeteo.svc/xml/1");

        try
        {
            HttpClient client = new();
            HttpResponseMessage response = await client.GetAsync(uri);

            if (response.IsSuccessStatusCode)
            {
                String content = await response.Content.ReadAsStringAsync();
                content = content.Substring(content.IndexOf("<XMLDataResult>") + 15);
                content = content.Substring(0, content.IndexOf("</XMLDataResult>"));
                lbTemp.Text = content + " °C";
            }
        }
        catch (Exception ex)
        {
            await this.DisplayAlert("Error", ex.Message, "OK");
        }
    }
}

vMeteo.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage 
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="TPMaui3.Views.vMeteo"
    Title="Météo"
>
    <VerticalStackLayout Spacing="20" Margin="10" >
        <Label
            Text="Météo"
            x:Name="lbMeteo"
            VerticalOptions="Center"
            HorizontalOptions="Center" 
            FontSize="Medium" 
            TextColor="{StaticResource Primary}"
        />
        <Label
            Text="?"
            x:Name="lbTemperature"
            VerticalOptions="Center"
            HorizontalOptions="Center" 
            FontSize="Medium" 
            TextColor="{StaticResource Secondary}"
        />
        <Label
            Text="?"
            x:Name="lbPression"
            VerticalOptions="Center"
            HorizontalOptions="Center" 
            FontSize="Medium" 
            TextColor="{StaticResource Secondary}"
        />
        <Label
            Text="?"
            x:Name="lbHumidite"
            VerticalOptions="Center"
            HorizontalOptions="Center" 
            FontSize="Medium" 
            TextColor="{StaticResource Secondary}"
        />
        <Label
            Text="?"
            x:Name="lbPrecipitationJour"
            VerticalOptions="Center"
            HorizontalOptions="Center" 
            FontSize="Medium" 
            TextColor="{StaticResource Secondary}"
        />
        <Label
            Text="?"
            x:Name="lbTemperatureRessentie"
            VerticalOptions="Center"
            HorizontalOptions="Center" 
            FontSize="Medium" 
            TextColor="{StaticResource Secondary}"
        />
        <Label
            Text="?"
            x:Name="lbVentDirection"
            VerticalOptions="Center"
            HorizontalOptions="Center" 
            FontSize="Medium" 
            TextColor="{StaticResource Secondary}"
        />
        <Label
            Text="?"
            x:Name="lbVentVitesse"
            VerticalOptions="Center"
            HorizontalOptions="Center" 
            FontSize="Medium" 
            TextColor="{StaticResource Secondary}"
        />
    </VerticalStackLayout>
</ContentPage>

vMeteo.xaml.cs

using System.Diagnostics.Metrics;
using System.Text.Json;
using TPMaui3.Models;

namespace TPMaui3.Views;

public partial class vMeteo : ContentPage
{
    public vMeteo()
    {
        InitializeComponent();
        Meteo();
    }

    private async void Meteo()
    {
        Uri uri = new("http://meteorestsrvmobile.lab3il.fr/RestServiceMeteo.svc/jsontmps");
        try
        {
            HttpClient client = new();
            HttpResponseMessage response = await client.GetAsync(uri);
            JsonSerializerOptions jsonSerializerOptions = new JsonSerializerOptions();

            if (response.IsSuccessStatusCode)
            {
                var result = await response.Content.ReadAsStringAsync();
                result = result.Replace("{\"JSONDataTmpsResult\":", "");
                result = result.Replace("}}", "}");

                var vMeteo = Newtonsoft.Json.JsonConvert.DeserializeObject<CMeteo>(result);
                lbMeteo.Text = "Relevé à " + vMeteo.DateReleve.ToString();
                lbTemperature.Text = "Temp: " + vMeteo.Temperature.ToString() + " °C";
                lbHumidite.Text = "Hum: " + vMeteo.Humidite.ToString() + " %";
                lbPression.Text = "Pres: " + vMeteo.Pression.ToString() + " hPa";
                lbTemperatureRessentie.Text = "TR: " + vMeteo.TemperatureRessentie.ToString() + " °C";
                lbPrecipitationJour.Text = "PrecJ: " + vMeteo.PrecipitationJour.ToString() + " mm";
                lbVentVitesse.Text = "Vit: " + vMeteo.VentVitesse.ToString() + " m/s";
                lbVentDirection.Text = "Vent: " + vMeteo.VentDirection.ToString();
            }
        }
        catch (Exception ex)
        {
            await this.DisplayAlert("Error", ex.Message, "OK");
        }
    }
}

CMeteo.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using TPMaui3.Views;

namespace TPMaui3.Models;

internal class CMeteo
{
    public CMeteo()
    {
    }

    public string DateReleve { get; set; }
    public string Temperature { get; set; }
    public string Pression { get; set; }
    public string Humidite { get; set; }
    public string PrecipitationJour { get; set; }
    public string TemperatureRessentie { get; set; }
    public string VentDirection { get; set; }
    public string VentVitesse { get; set; }
}

Upvotes: -7

DM-98
DM-98

Reputation: 665

HttpClient in mobile development is a little different from Web. The devices handle HttpClients themselves pretty well, and we don't have to worry much about Disposing it correctly by using nuget packages (Microsoft.Extensions.Http). So you can just fine use AddSingleton instead, or even use static readonly of the HttpClient. The .NET MAUI team made sure HttpClient class is configured this way.

Source from Microsoft:

The .NET MAUI templates map the HttpClient class to code that utilizes to the native networking stack of each platform. This enables an application to take advantage of platform-specific network configuration and optimization features

Upvotes: 5

Related Questions