I'm struggling to share a properties value across components in Blazor. Basically I have a button with an onclick event this sets a value on a function depending on the value another cshtml page should react to the value and it doesn't. The issue is that because both cshtml pages inherit the same function they have their own instance of the function. Here's my code so far:
the Function:
public class MenuFunctions : BlazorComponent, IMenuFunctions
{
public bool CollapseNavMenu
{
get ; set;
}
public void ToggleNavMenu()
{
CollapseNavMenu = !CollapseNavMenu;
}
}
The main button on NavMenuToggleComponent.cshtml:
#inherits MenuFunctions
<div class="pl-4 navbar navbar-dark">
<button class="navbar-toggler navbar-brand main-button" title="MENU" onclick=#ToggleNavMenu>
MENU
</button>
</div>
my NavMenu.cshtml file:
#inherits MenuFunctions
<div class="#(CollapseNavMenu ? "collapse" : null)" onclick=#ToggleNavMenu>
<ul class="nav flex-column">
<li class="nav-item px-3">
<NavLink class="nav-link" href="home">
<span class="oi oi-home" aria-hidden="true"></span> Home
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="frontpage">
<span class="oi oi-home" aria-hidden="true"></span> Front Page
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="counter">
<span class="oi oi-plus" aria-hidden="true"></span> Counter
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="" Match=NavLinkMatch.All>
<span class="oi oi-account-login" aria-hidden="true"></span> Login
</NavLink>
</li>
</ul>
</div>
putting it all together in my MainLayout.cshtml
#inherits BlazorLayoutComponent
<NavMenuToggleComponent></NavMenuToggleComponent>
<div class="sidebar">
<NavMenu />
</div>
<div class="main">
<div class="top-row px-4">
About
<NavLink class="nav-link pull-right" href="logout">
<span class="oi oi-account-logout" aria-hidden="true"></span> Logout
</NavLink>
</div>
<div class="content px-4">
#Body
</div>
</div>
so when I click the button in NavMenuToggleComponent.cshtml I want the CollapseNavMenu to react in the NavMenu.cshtml file
If I remove the use of the interface, then inject the components onto the pages as opposed to Inherit and then add the following into the startup:
services.AddSingleton<MenuFunctions>();
the pages will load, but I still get the same issue.
The solution here would be to bring the shared property to the place where it is common, in this case the MainLayout.cshtml and not make the components dependent on a common interface.
So the MainLayout.cshtml would hold the state in a new property and that property is bound to the two components.
You should not use DI for component classes, only for service providing classes and alike.
Related
Hello I am stuck on this problem today.
I have a web interface where you can log in.
See picture:
On the left side I have my navmenu with the different choices.
After the user has logged in I want the navmenu to change and show other menu items (change password, change email).
The problem is that with blazor the navmenu is always applied to all pages.
Here is my NavMenu.razor
<div class="#NavMenuCssClass" #onclick="ToggleNavMenu">
<nav class="flex-column">
<div class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="oi oi-home" aria-hidden="true"></span> Home
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="login">
<span class="oi oi-account-login" aria-hidden="true"></span> Login
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="register">
<span class="oi oi-plus" aria-hidden="true"></span> Registrieren
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="fetchdata">
<span class="oi oi-check" aria-hidden="true"></span> Email Prüfen
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="fetchdata">
<span class="oi oi-question-mark" aria-hidden="true"></span> Passwort Vergessen
</NavLink>
</div>
</nav>
How do I make it so that my page gets its own navmenu after login and the existing one does not change?
Here is my html part of my login page
<html>
<h1 class="title">Login</h1>
<br/>
<div class="row px-3">
<RadzenCard class="card">
<div class="row">
<div class="col-3" style="">
<h3 style="margin-top:3%; margin-left:30px;">Benutzername</h3>
</div>
<div class="col-5">
<RadzenTextBox #bind-Value=#_username class="email_input"></RadzenTextBox>
<p hidden=#errorMessagesEmail.NoSyntaxError class="errorMail">Ungültige Email Adresse</p>
<p hidden=#errorMessagesEmail.NoEmptyEmail class="errorMail">Bitte Email Adresse eingeben</p>
</div>
</div>
<br/>
<div class="row">
<div class="col-3">
<h3 style="margin-top:3%; margin-left:30px; ">Passwort</h3>
</div>
<div class="col-5">
<RadzenPassword #bind-Value=#_password class="password_input"></RadzenPassword>
<p hidden=#errorMessagesPassword.NoEmptyPassword class="passwordMessage">Bitte Passwort eingeben</p>
<p hidden=#errorMessagesPassword.RightCredentials class="passwordMessage">Benutzername oder Passwort falsch</p>
<p hidden=#errorMessagesPassword.NotToManyRequest class="passwordMessage">Zu viele Anfragen mit einem falschen Passwort</p>
<br/>
<p class="errorMail">#_loginErrorMessages</p>
<p hidden=#_logInFailed class="passwordMessage">Erfolgreich</p>
</div>
</div>
</RadzenCard>
<RadzenButton Click=#OnLogin class="rz-button" ButtonType="ButtonType.Submit" Text="Login"></RadzenButton>
</div>
Thanks for all Answers
If you need any more infos just let me Know
;P
You use <AuthorizeView> to display differing content depending on the user's authorization status. This is called authorization.
For authenticated users, you can display content specific to them inside the <Authorized>.
If user is not logged in and you want to show content only of unathorized users, place the content inside <NotAuthorized> element.
To enable authorization in your pages you need to enable authentication state in App.razor
App.razor:
<CascadingAuthenticationState>
<Router AppAssembly="#typeof(App).Assembly">
<Found Context="routeData">
<RouteView RouteData="#routeData" DefaultLayout="#typeof(MainLayout)"/>
<FocusOnNavigate RouteData="#routeData" Selector="h1"/>
</Found>
<NotFound>
<PageTitle>Not found</PageTitle>
<LayoutView Layout="#typeof(MainLayout)">
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
</CascadingAuthenticationState>
Then you need to update your NavMenu to show links accordingly, for example when a user is not logged in, show the login and registration menu but not email or password menu because those last 2 menus I assume are for authenticated users only.
NavMenu.razor
<div class="top-row ps-3 navbar navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="">BlazorApp1</a>
<button title="Navigation menu" class="navbar-toggler" #onclick="ToggleNavMenu">
<span class="navbar-toggler-icon"></span>
</button>
</div>
</div>
<div class="#NavMenuCssClass" #onclick="ToggleNavMenu">
<nav class="flex-column">
<div class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="oi oi-home" aria-hidden="true"></span> Home
</NavLink>
</div>
<AuthorizeView>
<NotAuthorized>
<div class="nav-item px-3">
<NavLink class="nav-link" href="login">
<span class="oi oi-account-login" aria-hidden="true"></span> Login
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="register">
<span class="oi oi-plus" aria-hidden="true"></span> Registrieren
</NavLink>
</div>
</NotAuthorized>
</AuthorizeView>
<AuthorizeView>
<Authorized>
<div class="nav-item px-3">
<NavLink class="nav-link" href="fetchdata">
<span class="oi oi-check" aria-hidden="true"></span> Email Prüfen
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="fetchdata">
<span class="oi oi-question-mark" aria-hidden="true"></span> Passwort Vergessen
</NavLink>
</div>
</Authorized>
</AuthorizeView>
</nav>
</div>
#code {
private bool collapseNavMenu = true;
private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;
private void ToggleNavMenu()
{
collapseNavMenu = !collapseNavMenu;
}
}
Output:
You are looking for AuthorizeView Component. For details see documentation.
Basically you can have NavMenu.razor like this:
<AuthorizeView>
<Authorized>
<AuthorizedMenu />
</Authorized>
<NotAuthorized>
<NotAuthorizedMenu />
</NotAuthorized>
</AuthorizeView>
with your current code being moved to the new NotAuthorizedMenu.razor component.
This should work, but I'm not at my VS atm to test it fully. So some changes might be needed.
Please note (from documentation):
The AuthorizeView component can be used in the NavMenu component (Shared/NavMenu.razor) to display a NavLink component (NavLink), but note that this approach only removes the list item from the rendered output. It doesn't prevent the user from navigating to the component.
I am in the closing stages of finishing my first Blazor WA app. However, I have a problem regarding my nav menu.
The nav menu (apart from the login button) is hidden until a login. The problem is once a user logs in the navbar doesn't update with the controls they are allowed to see based on their role.
I know to why this is as the nav menu have already been initialized based on the roles of nothing due to no JWT token, which at the point is correct. If I do a reload of the page (ctrl+f5) the menu populated correctly.
How can I update the state of the nav menu on login? any help would be really appreciated.
<div class="top-row pl-4 navbar navbar-dark">
<a class="navbar-brand" href="">Net2 Support Portal</a>
<button class="navbar-toggler" #onclick="ToggleNavMenu">
<span class="navbar-toggler-icon"></span>
</button>
</div>
<AuthorizeView>
Everyone can view the normal menu
#if (isAdmin || isDev || isSecondline || isAppEng || isUser)
{
<div class="#NavMenuCssClass" #onclick="ToggleNavMenu">
<ul class="nav flex-column">
<li class="nav-item px-3">
<NavLink class="nav-link" href="Overview" Match="NavLinkMatch.All">
<i class=" oi material-icons"> home </i>Home
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="Net2Users">
<span class="oi material-icons" aria-hidden="true">people</span>Users
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="Net2Departments">
<span class="oi material-icons" aria-hidden="true">people</span>Departments
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="AccessLevels">
<span class=" oi material-icons" aria-hidden="true">shield</span>AccessLevels
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="Timezones">
<span class="oi material-icons" aria-hidden="true">schedule</span>Timezones
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="Tokens">
<span class="oi material-icons" aria-hidden="true">payment</span>Tokens
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="Operators">
<span class="oi material-icons" aria-hidden="true">people</span>Operators
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="Net2Versioning">
<span class="oi material-icons" aria-hidden="true">analytics</span>Versioning
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="Database">
<span class="oi material-icons" aria-hidden="true">storage</span>Database
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="Devices">
<span class="oi material-icons" aria-hidden="true">devices</span>Devices
</NavLink>
</li>
</ul>
</div>
}
#*Only Secondline, AppsEngineers, Admin and Devs can access this*#
#if (isSecondline || isAppEng || isAdmin || isDev)
{
<div class="#NavMenuCssClass" #onclick="ToggleNavMenu">
<ul class="nav flex-column">
<li class="nav-item px-3">
<NavLink class="nav-link" href="Diagnostics" Match="NavLinkMatch.All">
<span class="oi material-icons" aria-hidden="true">health_and_safety</span>Diagnostics
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="Patches">
<span class="oi material-icons" aria-hidden="true">medical_services</span>Patches
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="ProFeatures">
<span class="oi material-icons" aria-hidden="true">featured_video</span>Pro Features
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="Tools">
<span class="oi material-icons" aria-hidden="true">build</span>Tools
</NavLink>
</li>
</ul>
</div>
}
</AuthorizeView>
<AuthorizeView>
<Authorized>
<div class="#NavMenuCssClass" #onclick="ToggleNavMenu">
<ul class="nav flex-column">
<li class="nav-item px-3">
#*Only Admin and Dev can access this*#
#if (isAdmin || isDev)
{
<NavLink class="nav-link" href="Admin">
<span class="oi material-icons" aria-hidden="true">admin_panel_settings</span> Admin Panel
</NavLink>
}
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="Logout">
<span class="oi material-icons" aria-hidden="true">logout</span> Logout
</NavLink>
</li>
</ul>
</div>
</Authorized>
<NotAuthorized>
<div class="#NavMenuCssClass" #onclick="ToggleNavMenu">
<ul class="nav flex-column">
<li class="nav-item px-3">
<NavLink class="nav-link" href="Login" Match="NavLinkMatch.All">
<span class="oi material-icons" aria-hidden="true">login</span> Login
</NavLink>
</li>
</ul>
</div>
</NotAuthorized>
</AuthorizeView>
#code {
[CascadingParameter]
public Task<AuthenticationState> AuthState { get; set; }
private bool collapseNavMenu = true;
public bool isAuthenticated { get; set; }
public bool isAdmin { get; set; }
public bool isUser { get; set; }
public bool isDev { get; set; }
public bool isSecondline { get; set; }
public bool isAppEng { get; set; }
public bool isTester { get; set; }
private string NavMenuCssClass => collapseNavMenu ? "collapse" : null;
private void ToggleNavMenu()
{
collapseNavMenu = !collapseNavMenu;
}
protected override async Task OnInitializedAsync()
{
var authState = await AuthState;
if (authState.User.Identity.IsAuthenticated)
{
isAuthenticated = true;
isUser = authState.User.IsInRole(UserRoles.User);
isDev = authState.User.IsInRole(UserRoles.Developer);
isSecondline = authState.User.IsInRole(UserRoles.Secondline);
isAppEng = authState.User.IsInRole(UserRoles.ApplicationEngineer);
isAdmin = authState.User.IsInRole(UserRoles.Administrator);
isTester = authState.User.IsInRole(UserRoles.Tester);
StateHasChanged();
}
}
}
Thanks everyone for there help. The solution was using <AuthorizeView Roles="#Roles.Administrator"> rather then the method I made. Thanks for everyone's time!
We have a starting page that is declared like this.
#page "/"
#inherits PageBase
#using GroupTool.Blazor.Core
#using Microsoft.Extensions.Configuration
#using GroupTool.Blazor.Extensions
#inject IConfiguration _configuration
#using Microsoft.AspNetCore.Authorization
#attribute [Authorize]
#inject DialogService _dialogService
<div class="container linkpagecontainer">
<div class="col-md-12 linkpagerowdiv">
<div class="row linkpagerow">
<div class="col col-md-5 d-none d-sm-flex flex-column grouplistbox groupboxleft">
The MainLayout used with this page is like this.
#inherits LayoutComponentBase
#using Microsoft.AspNetCore.Components.Authorization
#inject ILocalStorageService localStore
#inject NavigationManager NavigationManager
#using Blazored.LocalStorage;
#using Wur.GroupTool.Blazor.Core.Infrastructure;
<AuthorizeView>
<Authorized>
<div class="page mainpage">
<div class="sidebar">
<NavMenu />
</div>
<div class="main">
<div class="top-row px-4 auth">
#if (DataLoaded)
{
<div class="main-header"><h2>#CourseDetails.Name #CourseCode Period: #Year-#PeriodNumber</h2></div>
}
<LoginDisplay />
</div>
<div class="content px-4 maincontent">
<RadzenNotification />
<RadzenTooltip />
<RadzenDialog />
#Body
</div>
</div>
</div>
</Authorized>
<NotAuthorized>
<div class="page">
<div class="main">
<div class="top-row px-4 auth">
<LoginDisplay />
</div>
<div class="content px-4">
#Body
</div>
</div>
</div>
</NotAuthorized>
</AuthorizeView>
As you can see a NavMenu is added which is like this.
<div class="top-row pl-4 navbar navbar-dark navbarheader">
<a class="navbar-brand" href=""><img src="css/images/WUR_W.png" height="20"/> GroupTool</a>
<button class="navbar-toggler" #onclick="ToggleNavMenu">
<span class="navbar-toggler-icon"></span>
</button>
</div>
<div class="#NavMenuCssClass" #onclick="ToggleNavMenu">
<ul class="nav flex-column">
<li class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="oi oi-people" aria-hidden="true"></span> Groups
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="linkgroups">
<span class="oi oi-link-intact" aria-hidden="true"></span> Link Groups
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="schedule">
<span class="oi oi-calendar" aria-hidden="true"></span> Schedule
</NavLink>
</li>
</ul>
</div>
<footer class="footer">
<div class="container-fluid">
© #DateTime.Today.Year WUR<br />version #System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString()
</div>
</footer>
#code {
private bool collapseNavMenu = false;
private string NavMenuCssClass => collapseNavMenu ? "collapse" : null;
private void ToggleNavMenu()
{
collapseNavMenu = !collapseNavMenu;
}
}
Now the problem is that when I go to the startpage without a query string the menu shows like this.
When however I add a querystring like f.i. so.
https://localhost:44381/?CourseId=13890
The menu show up without the default set.
What do I need to do to get that working?
==EDIT==
I think it's a bug in Blazor. Take a look here: https://code-maze.com/query-strings-blazor-webassembly/ The article explains how to use query strings in Blazor but notice what happens to the menu in the images on the page. Exactly my problem.
==EDIT==
Reported a bug on Github: https://github.com/dotnet/aspnetcore/issues/31312
If I've understood your question correctly, what you want is to change
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
to
<NavLink class="nav-link" href="/" Match="NavLinkMatch.All">
this will allow the navlink matching to work with queryparameters
My goal is to get some data passed to common layout code. Code snippets of what I have but the value of linkedCyclones is not cascading to the lower component NavLinkedCyclones.
Not sure who to pass data into a layout component. I thought the cascade would do the trick but I'm either doing it wrong or it doesn't work the same way with layouts.
The LinkedSetIds is always null in the NavLinkedCyclones.razor
I welcome any suggestions.
NavCycloneMenu.razor
<CascadingValue Value="#linkedCyclones" Name="LinkedSets">
<AuthorizeView Roles="Admin, Tier2, Tier3">
<Authorized>
<li class="nav-item px-3">
<NavLink class="nav-link" href="CycloneCalculator/GasMix">
<span class="oi oi-beaker" aria-hidden="true"></span> Gas Mix
</NavLink>
</li>
</Authorized>
</AuthorizeView>
<AuthorizeView>
<Authorized>
<li class="nav-item px-3">
<NavLink class="nav-link" href="CycloneCalculator/CycloneSizing">
<span class="oi oi-calculator" aria-hidden="true"></span> Cyclone Sizing
</NavLink>
</li>
</Authorized>
</AuthorizeView>
</CascadingValue>
#code {
private int[] linkedCyclones { get; set; }
protected override void OnInitialized()
{
linkedCyclones = new int[] { 101, 202, 303 };
}
}
GasMix.razor
#layout CycloneLayout;
<div>
<h1>Gas Mix</h1>
</div>
CycloneLayout.razor
#inherits LayoutComponentBase
<div class="sidebar">
<NavCycloneMenu />
</div>
<div class="main">
<div class="top-row px-4 auth">
<LoginDisplay />
<a class="top-row-text" href="https://www.example.com/" target="_blank">About</a>
</div>
<div class="content px-4">
<NavLinkedCyclones />
#Body
</div>
</div>
NavLinkedCyclones.razor
<fieldset>
<legend>Linked Cyclones</legend>
#for (int i = 0; i < LinkedSetIds.Length - 1; i++)
{
<img class="img-linked-cyclone" src="images/CycloneLogoNoWhite.png" alt="Cyclone"> Cyclone #(i+1)
<div class="oi oi-arrow-thick-right" aria-hidden="true"></div>
<div class="oi oi-arrow-thick-right" aria-hidden="true"></div>
<div class="oi oi-arrow-thick-right" aria-hidden="true"></div>
}
<img class="img-linked-cyclone" src="images/CycloneLogoNoWhite.png" alt="Cyclone"> Cyclone #LinkedSetIds.Length
</fieldset>
#code{
[CascadingParameter(Name = "LinkedSets")]
public int[] LinkedSetIds { get; set; }
}
As far as I understand the Partial pages have only the cshtml code, while the ViewComponent have only the cs code.
Perhaps my approach is wrong, but I'm trying to render a complete page (cshtml + cshtml.cs) in another.
Real example.
Visual Studio 2017, ASP.NET Core 2.
NavBar.cshtml:
#page
#model MyProject.NavBarModel
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
<ul class="navbar-nav">
<li class="nav-item"><a class="nav-link" asp-page="/Machines">#Resources.Machines</a></li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">#Resources.Orders</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" asp-page="/RunningOrders">#Resources.Running <span class="badge badge-primary">#ViewData["running"]</span></a>
<a class="dropdown-item" asp-page="/OpenOrders">#Resources.Opened <span class="badge badge-primary">#ViewData["running"]</span></a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" asp-page="/SuspendedOrders">#Resources.Suspended <span class="badge badge-danger">#ViewData["running"]</span></a>
</div>
</li>
<li class="nav-item"><a class="nav-link" asp-page="/Tables">#Resources.Lists</a></li>
<li class="nav-item"><a class="nav-link" asp-page="/About">#Resources.About</a></li>
</ul>
</div>
NavBar.cshtml.cs
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using MyProject.Models;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace MyProject
{
public class NavBarModel : PageModel
{
private readonly MyContext _context;
public NavBarModel(MyContext context)
{
_context = context;
}
public List<Order> Orders { get; set; }
public async Task OnGetAsync()
{
Orders = await _context.Orders.ToListAsync();
ViewData["open"] = _context.Orders.Where(x => x.State == OrderStates.Open).Count();
ViewData["running"] = _context.Orders.Where(x => x.State == OrderStates.Running).Count();
ViewData["suspened"] = _context.Orders.Where(x => x.State == OrderStates.Suspended).Count();
}
}
}
_Layout.cshtml:
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top mb-2">
<a asp-page="/Index" class="navbar-brand">Production Assistant</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
#Html.Partial("NavBar", new NavBarModel())
</nav>
<div class="container body-content">
#RenderBody()
</div>
</body>
In this example I'm trying to add a Badge in the Navbar. Because the _Layout file has no code behind I had to put that in a separate Page (NavBar).
The problem is that when I try to render the page it asks for the constructor parameters. I'm afraid I've broken the dependency injection in this way.