Amir Imam
Amir Imam

Reputation: 1043

update MainLayout from child component in blazor .NET 8

I used to use a custom method to authorize the user in the previous Blazor projects like this:

MainLayout

@if(AppState.Me == null)
{
 <LoginView RefreshLayout=this.StateHasChanged />
}
else
{
 @Body
}
@code{
 [Inject]
 private AppStateManager AppState {get;set;}
}

LoginView

<button @onclick=LoginSubmit>Login</button>
@code{
 [Parameter]
 public Action RefreshLayout {get; set;}
 [Inject]
 private AppStateManager AppState {get;set;}
 private void LoginSubmit()
 {
    AppState.Me = GetUserFromStorage(); //Login method
    RefreshLayout();
 }
}

This method was working in Blazor .NET 7 and previous versions. In .NET 8 when I use global auto render mode it doesn't work because the MainLayout is a static page.

I tried to make a route and another empty layout for the LoginView and navigate to it if the user is not authorized, but AppState.Me is always null in MainLayout because again it is a static page So how to implement this method without using built-in authentication

Upvotes: 0

Views: 336

Answers (1)

Fengzhi Zhou
Fengzhi Zhou

Reputation: 1657

You could try CascadingValue to pass the value and the authentication logic needs more steps.

1.In both program.cs of your global auto render project

builder.Services.AddScoped<AppStateManager>()

2.MainLayout

@inherits LayoutComponentBase
@inject AppStateManager AppState
@using BlazorApp3.Client.Pages

<CascadingValue Value="AppState" IsFixed="false">
    @if (AppState.Me == null)
    {
        ...
    }
    else
    {
        ...
    }
</CascadingValue>

@code {
    protected override void OnInitialized()
    {
        AppState.OnChange += StateHasChanged;
    }

    public void Dispose()
    {
        AppState.OnChange -= StateHasChanged;
    }
}

3.LoginView

@page "/loginview"

<PageTitle>LoginView</PageTitle>

<button class="btn btn-primary" @onclick="LoginSubmit">Login</button>

@code {

    [Inject] AppStateManager AppState { get; set; }
    [Inject] NavigationManager NavigationManager { get; set; }

    private void LoginSubmit()
    {
        //Or your auth and login logic, here to simply show
        AppState.Me = "UserPassed";
        AppState.UserState();
        NavigationManager.NavigateTo("/index");
    }
}

4.AppStateManager

public class AppStateManager
{
    public string? Me { get; set; } = null;

    public event Action OnChange;

    public void UserState() => OnChange?.Invoke();
}

enter image description here enter image description here

Upvotes: 1

Related Questions