It works: client service + server service + utility service to know server uri when app is running

This commit is contained in:
2026-01-28 22:34:01 +01:00
parent a74065f768
commit fc8d59ae12
7 changed files with 125 additions and 9 deletions

View File

@@ -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<ServiceResponse<int>> Register(UserRegister request)
{
var result = await _http.PostAsJsonAsync("api/auth/register", request);
return await result.Content.ReadFromJsonAsync<ServiceResponse<int>>();
}
// public async Task<ServiceResponse<string>> Login(UserLogin request)
// {
// var result = await _http.PostAsJsonAsync("api/auth/login", request);
// return await result.Content.ReadFromJsonAsync<ServiceResponse<string>>();
// }
//
// public async Task<ServiceResponse<bool>> ChangePassword(UserChangePassword request)
// {
// var result = await _http.PostAsJsonAsync("api/auth/change-password", request.Password);
// return await result.Content.ReadFromJsonAsync<ServiceResponse<bool>>();
// }
// public async Task<bool> IsUserAuthenticated()
// {
// return (await _authenticationStateProvider.GetAuthenticationStateAsync()).User.Identity.IsAuthenticated;
// }
}

View File

@@ -0,0 +1,11 @@
using Sandbox.Models.ViewModels;
namespace Sandbox.App.Services.AuthService;
public interface IAuthService
{
Task<ServiceResponse<int>> Register(UserRegister request);
// Task<ServiceResponse<string>> Login(UserLogin request);
// Task<ServiceResponse<bool>> ChangePassword(UserChangePassword request);
// Task<bool> IsUserAuthenticated();
}

View File

@@ -1,6 +1,7 @@
@page "/register" @page "/register"
@using Sandbox.Models.ViewModels @using Sandbox.Models.ViewModels
@inject Sandbox.App.Services.AuthService.IAuthService AuthService
@* @inject AuthenticationStateProvider AuthenticationStateProvider *@ @* @inject AuthenticationStateProvider AuthenticationStateProvider *@
@* @inject NavigationManager NavigationManager *@ @* @inject NavigationManager NavigationManager *@
@@ -51,7 +52,7 @@
@code { @code {
[SupplyParameterFromForm] private UserRegister user { get; set; } [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 message = string.Empty;
private string messageCssClass = string.Empty; private string messageCssClass = string.Empty;
@@ -61,8 +62,9 @@
async Task HandleRegistration() async Task HandleRegistration()
{ {
var response = await _http.PostAsJsonAsync("/api/register", user); // var response = await _http.PostAsJsonAsync("/api/register", user);
var result = await response.Content.ReadFromJsonAsync<ServiceResponse<int>>(); // var result = await response.Content.ReadFromJsonAsync<ServiceResponse<int>>();
var result = await AuthService.Register(user);
message = result.Message; message = result.Message;
messageCssClass = result.Success ? "text-success" : "text-danger"; messageCssClass = result.Success ? "text-success" : "text-danger";
} }

50
HttpClientSetupService.cs Normal file
View File

@@ -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<IServerAddressesFeature>();
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;
}
}

View File

@@ -1,6 +1,9 @@
using Sandbox;
using Sandbox.Components; using Sandbox.Components;
using Sandbox.Models.ViewModels; using Sandbox.Models.ViewModels;
using Sandbox.Services.AuthService; using Sandbox.Services.AuthService;
using ClientServices = Sandbox.App.Services;
using ServerServices = Sandbox.Services;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
@@ -8,8 +11,16 @@ var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorComponents() builder.Services.AddRazorComponents()
.AddInteractiveServerComponents(); .AddInteractiveServerComponents();
// Blazor client services
builder.Services.AddScoped<ClientServices.AuthService.IAuthService, ClientServices.AuthService.AuthService>();
// Blazor server services
builder.Services.AddScoped<IAuthService, AuthService>(); builder.Services.AddScoped<IAuthService, AuthService>();
// Get server base address when application starts to properly configure HttpClient for client service to call server service
builder.Services.AddSingleton<HttpClient>();
builder.Services.AddSingleton<IHostedService, HttpClientSetupService>();
var app = builder.Build(); var app = builder.Build();
// Configure the HTTP request pipeline. // 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. // 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.UseHsts();
} }
app.UseStatusCodePagesWithReExecute("/not-found", createScopeForStatusCodePages: true); app.UseStatusCodePagesWithReExecute("/not-found", createScopeForStatusCodePages: true);
app.UseHttpsRedirection(); app.UseHttpsRedirection();
app.UseAntiforgery(); app.UseAntiforgery();
app.MapPost("/api/register", async (UserRegister request, IAuthService authService) => // Blazor server routing
await authService.Register(request.Email, request.Password)); app.MapPost("/api/auth/register", async (UserRegister request, IAuthService authService) =>
await authService.Register(request));
app.MapStaticAssets(); app.MapStaticAssets();
app.MapRazorComponents<App>() app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode(); .AddInteractiveServerRenderMode();
app.Run(); app.Run();

View File

@@ -4,12 +4,12 @@ namespace Sandbox.Services.AuthService;
public class AuthService : IAuthService public class AuthService : IAuthService
{ {
public async Task<ServiceResponse<int>> Register(string userName, string password) public async Task<ServiceResponse<int>> Register(UserRegister userRegister)
{ {
return new ServiceResponse<int> return new ServiceResponse<int>
{ {
Data = 1, Data = 1,
Message = $"Got register request with user name {userName}", Message = $"Got register request with e-mail {userRegister.Email}",
Success = true Success = true
}; };
} }

View File

@@ -4,5 +4,5 @@ namespace Sandbox.Services.AuthService;
public interface IAuthService public interface IAuthService
{ {
Task<ServiceResponse<int>> Register(string userName, string password); Task<ServiceResponse<int>> Register(UserRegister userRegister);
} }