Reputation: 1631
I am attempting to redirect from a razor component to a razor page. If user is not authorized I want to redirect from current razor component to Login Razor Page.
I have redirect to login component
public class RedirectToLogin : ComponentBase
{
[Inject]
protected NavigationManager NavigationManager { get; set; }
protected override void OnInitialized()
{
NavigationManager.NavigateTo("./Identity/Account/Login",true);
}
}
this line throws an error NavigationManager.NavigateTo("./Identity/Account/Login");
Microsoft.AspNetCore.Components.NavigationException: 'Exception of type 'Microsoft.AspNetCore.Components.NavigationException' was thrown.'
The assumption i have come to is that the problem is routing from a razor component to a razor page.
Upvotes: 5
Views: 5723
Reputation: 33
Based on Ash´s comment I made this simpler RedirectToRazorPage.razor component. When you need to navigate from blazor to razor page you just add "/redirectToRazorPage" as a prefix
@page "/redirectToRazorPage/{url}"
@inject NavigationManager Navigation
@code {
[Parameter]
public string url { get; set; }
protected override async Task OnInitializedAsync()
{
Navigation.NavigateTo(url, true);
await base.OnInitializedAsync();
}
}
Upvotes: 0
Reputation: 3651
If someone is looking for a complete solution, this is how I did it.
Step 1:
Create a razor component named RedirectToLogin.razor
wherever you want.
For eg: I'm creating it inside Areas/Identity/Components
And add the following code to this file:
@inject NavigationManager Navigation
@code {
[Parameter]
public string ReturnUrl { get; set; }
protected override async Task OnInitializedAsync()
{
ReturnUrl = "~/" + ReturnUrl;
Navigation.NavigateTo("Identity/Account/Login?returnUrl=" + ReturnUrl, true);
await base.OnInitializedAsync();
}
}
Step 2:
Use this component from App.razor
inside <NotAuthorized></NotAuthorized>
:
@inject NavigationManager Navigation
@using HMT.Web.Server.Areas.Identity.Components
<CascadingAuthenticationState>
<Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
<NotAuthorized>
@if (!context.User.Identity.IsAuthenticated)
{
<RedirectToLogin ReturnUrl="@Navigation.ToBaseRelativePath(Navigation.Uri)" />
}
else
{
<p role="alert">Sorry, you're not authorized to view this page.</p>
}
</NotAuthorized>
</AuthorizeRouteView>
<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>
https://github.com/akhanalcs/blazor-server-auth/tree/feature/LayoutWithIdentityPages
Start the app and try to get to an authorized view from the browser (Counter page here as an example):
You'll be redirected to Login page:
You'll log in successfully and get to the Counter page:
Upvotes: 2
Reputation: 91
This is an easy fix, it actually has nothing to do with authorization or so. You're doing the navigation part right. The problem here is that for some reason you can't use NavigationManager.NavigateTo()
in OnInitialized()
. It always throws this exception as you might have figured out already.
But the good thing is: The workaround is simple, yet not amazing: You just move NavigationManager.NavigateTo()
into OnAfterRender()
. That method gets called after the component has been rendered, so its close enough. However your page gets rendered, meaning you would need to handle that.
The answers to this question also answer yours.
Upvotes: 0
Reputation: 1631
I got a redirect to a not authorized page, using the Router below.
<Router AppAssembly="@typeof(Program).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
<NotAuthorized>
<div class="container">
<h1>Sorry</h1>
<p>You're not authorized to reach this page.</p>
<p>You may need to log in as a different user.</p>
<a href="Identity/Account/Login">Log in</a>
</div>
@*<RedirectToLogin />*@
</NotAuthorized>
<Authorizing>
<div class="container">
<h1>Authentication in progress</h1>
<p>Leave your hands on the keyboard, scanning your fingerprints. Ain't technology grand.</p>
</div>
</Authorizing>
</AuthorizeRouteView>
</Found>
<NotFound>
<CascadingAuthenticationState>
<LayoutView Layout="@typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</CascadingAuthenticationState>
</NotFound>
</Router>
This sufficed for the app for now.
Upvotes: 1