diff --git a/Jugenddienst Stunden/Infrastructure/HttpClientRegistration.cs b/Jugenddienst Stunden/Infrastructure/HttpClientRegistration.cs new file mode 100644 index 0000000..45a5adf --- /dev/null +++ b/Jugenddienst Stunden/Infrastructure/HttpClientRegistration.cs @@ -0,0 +1,29 @@ +using Jugenddienst_Stunden.Interfaces; +using Microsoft.Extensions.DependencyInjection; +using System.Net.Http; + +namespace Jugenddienst_Stunden.Infrastructure; + +internal static class HttpClientRegistration { + /// + /// Registriert den ApiClient mit einem SocketsHttpHandler als primären MessageHandler. + /// Vermeidet den Android-spezifischen Cast-Fehler in Xamarin.Android.Net.AndroidMessageHandler. + /// + public static IServiceCollection AddApiHttpClient(this IServiceCollection services, ApiOptions options) { + if (services is null) + throw new ArgumentNullException(nameof(services)); + if (options is null) + throw new ArgumentNullException(nameof(options)); + + // ApiOptions als Singleton bereitstellen (kann nach Bedarf angepasst werden) + services.AddSingleton(options); + + // HttpClient für ApiClient registrieren und einen SocketsHttpHandler verwenden. + // SocketsHttpHandler vermeidet das problematische Casting, das bei AndroidMessageHandler + // zur InvalidCastException (URLConnectionInvoker -> HttpURLConnection) führt. + services.AddHttpClient() + .ConfigurePrimaryHttpMessageHandler(() => new SocketsHttpHandler()); + + return services; + } +} diff --git a/Jugenddienst Stunden/Jugenddienst Stunden.csproj b/Jugenddienst Stunden/Jugenddienst Stunden.csproj index d024a71..cb55cc9 100644 --- a/Jugenddienst Stunden/Jugenddienst Stunden.csproj +++ b/Jugenddienst Stunden/Jugenddienst Stunden.csproj @@ -263,6 +263,7 @@ + diff --git a/Jugenddienst Stunden/MauiProgram.cs b/Jugenddienst Stunden/MauiProgram.cs index 560f694..1803843 100644 --- a/Jugenddienst Stunden/MauiProgram.cs +++ b/Jugenddienst Stunden/MauiProgram.cs @@ -9,6 +9,7 @@ using Microsoft.Extensions.Logging; using ZXing.Net.Maui.Controls; using System.Net.Http; using Jugenddienst_Stunden.ViewModels; +using System.Net; namespace Jugenddienst_Stunden; @@ -32,7 +33,7 @@ public static class MauiProgram { //#if DEBUG // if (string.IsNullOrWhiteSpace(GlobalVar.ApiKey)) { // GlobalVar.ApiKey = Preferences.Default.Get("apiKey", - // "MTQxfHNkdFptQkNZTXlPT3ZyMHNBZDl0UnVxNExMRXxodHRwOi8vaG91cnMuZGF1bmkubWluZS5udTo4MS9hcHBhcGk="); + // "MTQxfHNkdFptQkNZTXlPT3ZyMHxodHRwOi8vaG91cnMuZGF1bmkubWluZS5udTo4MS9hcHBhcGk="); // GlobalVar.Name = Preferences.Default.Get("name", "Testserver: Isabell"); // GlobalVar.Surname = Preferences.Default.Get("surname", "Biasi"); // GlobalVar.EmployeeId = Preferences.Default.Get("EmployeeId", 141); @@ -42,6 +43,10 @@ public static class MauiProgram { // builder.Logging.AddDebug(); //#endif + // ApiClient registrieren: SocketsHttpHandler als Primary Handler (vermeidet AndroidMessageHandler-Castfehler) + var apiOptions = new Infrastructure.ApiOptions { BaseUrl = GlobalVar.ApiUrl, Timeout = TimeSpan.FromSeconds(15) }; + builder.Services.AddApiHttpClient(apiOptions); + // DI: AlertService für globale Alerts (z. B. leere ApiUrl) builder.Services.AddSingleton(); @@ -50,17 +55,23 @@ public static class MauiProgram { // DI: ApiOptions IMMER aus aktuellen Settings erzeugen (nicht beim Start einfrieren) builder.Services.AddTransient(sp => new ApiOptions { - BaseUrl = sp.GetRequiredService().ApiUrl, Timeout = TimeSpan.FromSeconds(15) + BaseUrl = sp.GetRequiredService().ApiUrl, + Timeout = TimeSpan.FromSeconds(15) }); // Token Provider soll ebenfalls aus Settings/Preferences lesen builder.Services.AddSingleton(); // HttpClient + ApiClient - // Configure HttpClient with RequestLoggingHandler and disable automatic redirects for diagnosis + // Configure HttpClient with SocketsHttpHandler (managed) and RequestLoggingHandler builder.Services.AddTransient(); builder.Services.AddSingleton(sp => { - var nativeHandler = new HttpClientHandler { AllowAutoRedirect = false }; + var nativeHandler = new SocketsHttpHandler { + AllowAutoRedirect = false, + AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate, + PooledConnectionLifetime = TimeSpan.FromMinutes(5), + ConnectTimeout = TimeSpan.FromSeconds(10) + }; var logging = sp.GetRequiredService(); logging.InnerHandler = nativeHandler; // HttpClient.Timeout will be adjusted by ApiClient if needed @@ -95,16 +106,16 @@ public static class MauiProgram { // DI: Validatoren builder.Services.AddSingleton(); - // DI: Services & Repositories - builder.Services.AddSingleton(); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(); + // DI: Services & Repositories + builder.Services.AddSingleton(); + builder.Services.AddSingleton(); + builder.Services.AddSingleton(); - // DI: Views/ViewModels - builder.Services.AddTransient(); - builder.Services.AddTransient(); - builder.Services.AddTransient(); - builder.Services.AddTransient(); + // DI: Views/ViewModels + builder.Services.AddTransient(); + builder.Services.AddTransient(); + builder.Services.AddTransient(); + builder.Services.AddTransient(); return builder.Build(); }