I use the default Blazor NavMenu component and want to disable it when the user opens a window. In my app the input data from the user on the opened page has to be validated first before the user is allowed to click another item on the NavMenu.
I use the default Blazor NavMenu component and want to disable it when the user opens a window. In my app the input data from the user on the opened page has to be validated first before the user is allowed to click another item on the NavMenu.
Share Improve this question edited Mar 4 at 1:34 Zhi Lv 22k1 gold badge27 silver badges37 bronze badges asked Mar 2 at 14:40 VinceBVinceB 212 bronze badges2 Answers
Reset to default 2Wrap the links you only want shown when authorized in AuthorizeView
.
Here's a demo:
<AuthorizeView>
<Authorized>
<p>Hello, @context.User.Identity?.Name!</p>
<p><button @onclick="HandleClick">Authorized Only Button</button></p>
</Authorized>
<NotAuthorized>
<p>You're not authorized.</p>
</NotAuthorized>
</AuthorizeView>
The Microsoft Docs article is here: https://learn.microsoft/en-us/aspnet/core/blazor/security/?view=aspnetcore-9.0&tabs=visual-studio#authorizeview-component
As MrC aka Shaun Curtis said, you can add AuthorizeView in the NavMenu component.
In the AuthorizedView, you can add NavLink
both in the Authorized
and NotAuthorized
, in the NotAuthorized
area, disable the NavLink
using BootStrap Pointer events(add pe-none
class, you can also disable the link by adding custom CSS style.)
<AuthorizeView>
<Authorized>
<div class="nav-item px-3">
<NavLink class="nav-link" href="auth">
<span class="bi bi-lock-nav-menu" aria-hidden="true"></span> Auth Required
</NavLink>
</div>
</Authorized>
<NotAuthorized>
<div class="nav-item px-3">
<NavLink class="nav-link pe-none" href="auth" style="">
<span class="bi bi-lock-nav-menu" aria-hidden="true"></span> AuthRequired(Disabled)
</NavLink>
</div>
</NotAuthorized>
</AuthorizeView>
Besides, you can also use AuthenticationStateProvider in NavMenu, based on the user's IsAuthenticated status to add NavLink, add the following code in the NavMenu component:
@inject AuthenticationStateProvider AuthenticationStateProvider
@using Microsoft.AspNetCore.Components.Authorization
@code {
private string? currentUrl;
private bool isAuthenticated;
protected override async Task OnInitializedAsync()
{
currentUrl = NavigationManager.ToBaseRelativePath(NavigationManager.Uri);
NavigationManager.LocationChanged += OnLocationChanged;
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
isAuthenticated = authState.User.Identity?.IsAuthenticated ?? false;
}
Then use the following code to add NavLink:
<div class="nav-item px-3">
@if (isAuthenticated)
{
<NavLink class="nav-link" href="weather">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Weather
</NavLink>
}
else
{
<NavLink class="nav-link pe-none" href="weather">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Weather(Disabled)
</NavLink>
}
</div>
The result as below:
Before login, the NavLink is disabled
Once you have successfully logged in, NavLink is clickable, and you can navigate to the relevant page:
The NavMenu component like this:
@implements IDisposable
@inject NavigationManager NavigationManager
@inject AuthenticationStateProvider AuthenticationStateProvider
@using Microsoft.AspNetCore.Components.Authorization
<div class="top-row ps-3 navbar navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="">BlazorServerIdentity</a>
</div>
</div>
<input type="checkbox" title="Navigation menu" class="navbar-toggler" />
<div class="nav-scrollable" onclick="document.querySelector('.navbar-toggler').click()">
<nav class="nav flex-column">
<div class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="bi bi-house-door-fill-nav-menu" aria-hidden="true"></span> Home
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="counter">
<span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> Counter
</NavLink>
</div>
<div class="nav-item px-3">
@if (isAuthenticated)
{
<NavLink class="nav-link" href="weather">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Weather
</NavLink>
}
else
{
<NavLink class="nav-link pe-none" href="weather">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Weather(Disabled)
</NavLink>
}
</div>
<AuthorizeView>
<Authorized>
<div class="nav-item px-3">
<NavLink class="nav-link" href="auth">
<span class="bi bi-lock-nav-menu" aria-hidden="true"></span> Auth Required
</NavLink>
</div>
</Authorized>
<NotAuthorized>
<div class="nav-item px-3">
<NavLink class="nav-link pe-none" href="auth" style="">
<span class="bi bi-lock-nav-menu" aria-hidden="true"></span> AuthRequired(Disabled)
</NavLink>
</div>
</NotAuthorized>
</AuthorizeView>
<AuthorizeView>
<Authorized>
<div class="nav-item px-3">
<NavLink class="nav-link" href="Account/Manage">
<span class="bi bi-person-fill-nav-menu" aria-hidden="true"></span> @context.User.Identity?.Name
</NavLink>
</div>
<div class="nav-item px-3">
<form action="Account/Logout" method="post">
<AntiferyToken />
<input type="hidden" name="ReturnUrl" value="@currentUrl" />
<button type="submit" class="nav-link">
<span class="bi bi-arrow-bar-left-nav-menu" aria-hidden="true"></span> Logout
</button>
</form>
</div>
</Authorized>
<NotAuthorized>
<div class="nav-item px-3">
<NavLink class="nav-link" href="Account/Register">
<span class="bi bi-person-nav-menu" aria-hidden="true"></span> Register
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="Account/Login">
<span class="bi bi-person-badge-nav-menu" aria-hidden="true"></span> Login
</NavLink>
</div>
</NotAuthorized>
</AuthorizeView>
</nav>
</div>
@code {
private string? currentUrl;
private bool isAuthenticated;
protected override async Task OnInitializedAsync()
{
currentUrl = NavigationManager.ToBaseRelativePath(NavigationManager.Uri);
NavigationManager.LocationChanged += OnLocationChanged;
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
isAuthenticated = authState.User.Identity?.IsAuthenticated ?? false;
}
private void OnLocationChanged(object? sender, LocationChangedEventArgs e)
{
currentUrl = NavigationManager.ToBaseRelativePath(e.Location);
StateHasChanged();
}
public void Dispose()
{
NavigationManager.LocationChanged -= OnLocationChanged;
}
}