I created a test application to show my problem using Blazor Hybrid with .NET MAUI (.net 9) with the AuthenticationState of a user.
My test project on github: https://github.com/tPeif/blazorhybrid_authProblem
There are 2 components ArticleCategoryComponentExtra
and ArticleCategoryHtmlComponent
.The content is wrapped in a AuthorizeView
. Both components show a list of existing article categories and should show a Popup to add a new ArticeCategory
by clicking the button with id addCategorybtn
.
After completing the modal and clicking on the save button, the SaveDetail
Function is called.
private async Task SaveDetail()
{
// user is logged in
var ok = await CheckAuthentication();
try
{
await ArticleCategoryService.Add(_selectedDetail);
// user is logged in
var ok1 = await CheckAuthentication();
await Load();
// user is logged in
var ok2 = await CheckAuthentication();
ShowCategoryDetail = false;
var ok3 = await CheckAuthentication();
}
catch (Exception ex)
{
string action = _selectedDetail.Id == 0 ? "add" : "update";
_logger.LogError(ex, "Cannot {action} the category '{categoryName}'", action, _selectedDetail.Name);
}
}
[Inject]
public AuthenticationStateProvider AuthenticationStateProvider { get; set; } = default!;
private async Task<bool> CheckAuthentication()
{
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
if (!user.Identity.IsAuthenticated)
{
// Redirect to login or show an error message
_logger.LogError("User not logged in anymore");
return false;
}
return true;
}
As you can see I'm checking the current authenticationState several times. At the end of the function the user is logged in and the modal is removed.
The pages lifecycle event are called serveral times to update the page but at one moment the OnInitialized is called again, what should mean (at least for me) the page is completely re-rendered and this is the moment the user isn't longer logged in.
Do anyone have an idea why the application behave like this and what I should do to avoid the logout of the user ?
The problem is that when you close the dialog component the application resets. Add a guid Id to the form and you will see that you get a new instance every time you click the save button on the dialog.
That really puzzled me for a while until I saw the html form
tags.
<form>
<div class="mb-3">
<label for="id" class="form-label">Id</label>
<InputNumber class="form-control" id="id" @bind-Value="@Category.Id" readonly />
</div>
<div class="mb-3">
<label for="name" class="form-label">Name</label>
<InputText class="form-control" id="name" @bind-Value="@Category.Name" />
</div>
<div class="d-flex flex-row mx-2">
<button type="button" @onclick="SaveDetail" class="btn btn-primary"><i class="bi bi-floppy" /> Speichern</button>
</div>
</form>
What's happening is when you click the button, the form is being posted back to the server. Remove the form
, or set the button type to type="button"
and the problem goes away. No more posting.
You probably should be using EditForm
.