Reputation: 30334
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
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
Reputation: 2000
Use as follows for .Net6 and .Net7:
builder.Services.AddScoped(sp => new HttpClient { });
Upvotes: 6
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
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