From fc8d59ae127a62afdf7a03fdc116f35b6b84c17c Mon Sep 17 00:00:00 2001 From: postb99 Date: Wed, 28 Jan 2026 22:34:01 +0100 Subject: [PATCH] It works: client service + server service + utility service to know server uri when app is running --- App.Services/AuthService/AuthService.cs | 40 +++++++++++++++++++ App.Services/AuthService/IAuthService.cs | 11 ++++++ Components/Pages/Account/Register.razor | 8 ++-- HttpClientSetupService.cs | 50 ++++++++++++++++++++++++ Program.cs | 19 +++++++-- Services/AuthService/AuthService.cs | 4 +- Services/AuthService/IAuthService.cs | 2 +- 7 files changed, 125 insertions(+), 9 deletions(-) create mode 100644 App.Services/AuthService/AuthService.cs create mode 100644 App.Services/AuthService/IAuthService.cs create mode 100644 HttpClientSetupService.cs diff --git a/App.Services/AuthService/AuthService.cs b/App.Services/AuthService/AuthService.cs new file mode 100644 index 0000000..6bed95d --- /dev/null +++ b/App.Services/AuthService/AuthService.cs @@ -0,0 +1,40 @@ +using Microsoft.AspNetCore.Components.Authorization; +using Sandbox.Models.ViewModels; + +namespace Sandbox.App.Services.AuthService; + +public class AuthService : IAuthService +{ + private readonly HttpClient _http; + //private readonly AuthenticationStateProvider _authenticationStateProvider; + + // public AuthService(HttpClient httpClient, AuthenticationStateProvider authenticationStateProvider) + public AuthService(HttpClient httpClient) + { + _http = httpClient; + //_authenticationStateProvider = authenticationStateProvider; + } + + public async Task> Register(UserRegister request) + { + var result = await _http.PostAsJsonAsync("api/auth/register", request); + return await result.Content.ReadFromJsonAsync>(); + } + + // public async Task> Login(UserLogin request) + // { + // var result = await _http.PostAsJsonAsync("api/auth/login", request); + // return await result.Content.ReadFromJsonAsync>(); + // } + // + // public async Task> ChangePassword(UserChangePassword request) + // { + // var result = await _http.PostAsJsonAsync("api/auth/change-password", request.Password); + // return await result.Content.ReadFromJsonAsync>(); + // } + + // public async Task IsUserAuthenticated() + // { + // return (await _authenticationStateProvider.GetAuthenticationStateAsync()).User.Identity.IsAuthenticated; + // } +} \ No newline at end of file diff --git a/App.Services/AuthService/IAuthService.cs b/App.Services/AuthService/IAuthService.cs new file mode 100644 index 0000000..42f1508 --- /dev/null +++ b/App.Services/AuthService/IAuthService.cs @@ -0,0 +1,11 @@ +using Sandbox.Models.ViewModels; + +namespace Sandbox.App.Services.AuthService; + +public interface IAuthService +{ + Task> Register(UserRegister request); + // Task> Login(UserLogin request); + // Task> ChangePassword(UserChangePassword request); + // Task IsUserAuthenticated(); +} \ No newline at end of file diff --git a/Components/Pages/Account/Register.razor b/Components/Pages/Account/Register.razor index 935b318..8da9d07 100644 --- a/Components/Pages/Account/Register.razor +++ b/Components/Pages/Account/Register.razor @@ -1,6 +1,7 @@ @page "/register" @using Sandbox.Models.ViewModels +@inject Sandbox.App.Services.AuthService.IAuthService AuthService @* @inject AuthenticationStateProvider AuthenticationStateProvider *@ @* @inject NavigationManager NavigationManager *@ @@ -51,7 +52,7 @@ @code { [SupplyParameterFromForm] private UserRegister user { get; set; } - HttpClient _http = new() { BaseAddress = new("https://localhost:7122") }; + //HttpClient _http = new() { BaseAddress = new("https://localhost:7122") }; private string message = string.Empty; private string messageCssClass = string.Empty; @@ -61,8 +62,9 @@ async Task HandleRegistration() { - var response = await _http.PostAsJsonAsync("/api/register", user); - var result = await response.Content.ReadFromJsonAsync>(); + // var response = await _http.PostAsJsonAsync("/api/register", user); + // var result = await response.Content.ReadFromJsonAsync>(); + var result = await AuthService.Register(user); message = result.Message; messageCssClass = result.Success ? "text-success" : "text-danger"; } diff --git a/HttpClientSetupService.cs b/HttpClientSetupService.cs new file mode 100644 index 0000000..6083b5b --- /dev/null +++ b/HttpClientSetupService.cs @@ -0,0 +1,50 @@ +using Microsoft.AspNetCore.Hosting.Server; +using Microsoft.AspNetCore.Hosting.Server.Features; + +namespace Sandbox; + +public class HttpClientSetupService( + HttpClient httpClient, + IServer server, + IHostApplicationLifetime applicationLifetime) + : BackgroundService +{ + private readonly HttpClient _httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient)); + private readonly IServer _server = server ?? throw new ArgumentNullException(nameof(server)); + private readonly IHostApplicationLifetime _applicationLifetime = applicationLifetime ?? throw new ArgumentNullException(nameof(applicationLifetime)); + + protected override Task ExecuteAsync(CancellationToken stoppingToken) + { + var applicationStartedToken = _applicationLifetime.ApplicationStarted; + if (applicationStartedToken.IsCancellationRequested) + { + ConfigureHttpClient(); + } + else + { + applicationStartedToken.Register(ConfigureHttpClient); + } + + return Task.CompletedTask; + } + + private void ConfigureHttpClient() + { + var serverAddresses = _server.Features.Get(); + var address = serverAddresses.Addresses.FirstOrDefault(); + if (address == null) + { + // Default ASP.NET Core Kestrel endpoint + address = "http://localhost:5000"; + } + else + { + address = address.Replace("*", "localhost", StringComparison.Ordinal); + address = address.Replace("+", "localhost", StringComparison.Ordinal); + address = address.Replace("[::]", "localhost", StringComparison.Ordinal); + } + + var baseUri = new Uri(address); + _httpClient.BaseAddress = baseUri; + } +} \ No newline at end of file diff --git a/Program.cs b/Program.cs index d922a94..6267e17 100644 --- a/Program.cs +++ b/Program.cs @@ -1,6 +1,9 @@ +using Sandbox; using Sandbox.Components; using Sandbox.Models.ViewModels; using Sandbox.Services.AuthService; +using ClientServices = Sandbox.App.Services; +using ServerServices = Sandbox.Services; var builder = WebApplication.CreateBuilder(args); @@ -8,8 +11,16 @@ var builder = WebApplication.CreateBuilder(args); builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); +// Blazor client services +builder.Services.AddScoped(); + +// Blazor server services builder.Services.AddScoped(); +// Get server base address when application starts to properly configure HttpClient for client service to call server service +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); + var app = builder.Build(); // Configure the HTTP request pipeline. @@ -19,16 +30,18 @@ if (!app.Environment.IsDevelopment()) // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } + app.UseStatusCodePagesWithReExecute("/not-found", createScopeForStatusCodePages: true); app.UseHttpsRedirection(); app.UseAntiforgery(); -app.MapPost("/api/register", async (UserRegister request, IAuthService authService) => - await authService.Register(request.Email, request.Password)); +// Blazor server routing +app.MapPost("/api/auth/register", async (UserRegister request, IAuthService authService) => + await authService.Register(request)); app.MapStaticAssets(); app.MapRazorComponents() .AddInteractiveServerRenderMode(); -app.Run(); +app.Run(); \ No newline at end of file diff --git a/Services/AuthService/AuthService.cs b/Services/AuthService/AuthService.cs index f855537..87f22f2 100644 --- a/Services/AuthService/AuthService.cs +++ b/Services/AuthService/AuthService.cs @@ -4,12 +4,12 @@ namespace Sandbox.Services.AuthService; public class AuthService : IAuthService { - public async Task> Register(string userName, string password) + public async Task> Register(UserRegister userRegister) { return new ServiceResponse { Data = 1, - Message = $"Got register request with user name {userName}", + Message = $"Got register request with e-mail {userRegister.Email}", Success = true }; } diff --git a/Services/AuthService/IAuthService.cs b/Services/AuthService/IAuthService.cs index 83bf777..8381361 100644 --- a/Services/AuthService/IAuthService.cs +++ b/Services/AuthService/IAuthService.cs @@ -4,5 +4,5 @@ namespace Sandbox.Services.AuthService; public interface IAuthService { - Task> Register(string userName, string password); + Task> Register(UserRegister userRegister); } \ No newline at end of file