aspnetcore icon indicating copy to clipboard operation
aspnetcore copied to clipboard

NavigationManager.Navigate throws in OnInitialized if component is static

Open divvjson opened this issue 1 year ago • 1 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

Describe the bug

Consider a Blazor Web App with two components Home ("/") and Login ("/Login").

Home has render mode Interactive Server and Login has render mode Static Server.

If a user is already authenticated and hits https://example.com/Login I want to navigate the user to the Home component.

However, when doing so I get the following exception

image

This behavior previously worked fine in .NET 7 with hosting model Blazor Server.

Should this be handled differently with Blazor in .NET 8? If yes, how?

Expected Behavior

User should be navigated to the Home component.

Steps To Reproduce

Have a Blazor Web App with Cookie Authentication setup.

Program.cs

builder.Services
    .AddRazorComponents()
    .AddInteractiveServerComponents();

builder.Services
    .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.LoginPath = "/Login";
    });

builder.Services.AddAuthorization();
builder.Services.AddCascadingAuthenticationState();

var app = builder.Build();

...

app.UseAuthentication();
app.UseAuthorization();
app.UseAntiforgery();

app
    .MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

app.Run();

App.razor

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <base href="/" />
    <link rel="stylesheet" href="app.css" />
    <link rel="stylesheet" href="AuthDemo.styles.css" />
    <HeadOutlet />
</head>

<body>
    <Routes />
    <script src="_framework/blazor.web.js"></script>
</body>

</html>

Routes.razor

<Router AppAssembly="typeof(Program).Assembly">
    <Found Context="routeData">
        <AuthorizeRouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)" />
        <FocusOnNavigate RouteData="routeData" Selector="h1" />
    </Found>
</Router>

Exceptions (if any)

Microsoft.AspNetCore.Components.NavigationException: 'Exception_WasThrown'

.NET Version

8.0.201

Anything else?

.NET SDK:
 Version:           8.0.201
 Commit:            4c2d78f037
 Workload version:  8.0.200-manifests.e575128c

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.22631
 OS Platform: Windows
 RID:         win-x64
 Base Path:   C:\Program Files\dotnet\sdk\8.0.201\

.NET workloads installed:
There are no installed workloads to display.

Host:
  Version:      8.0.2
  Architecture: x64
  Commit:       1381d5ebd2

.NET SDKs installed:
  8.0.200 [C:\Program Files\dotnet\sdk]
  8.0.201 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 6.0.27 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 7.0.16 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 8.0.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.27 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 7.0.16 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 8.0.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 6.0.27 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 7.0.16 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 8.0.2 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

divvjson avatar Feb 24 '24 10:02 divvjson

It seems to work if I use the OnInitializedAsync lifecycle hook.

If this is the correct way to do it feel free to close the issue.

protected override async Task OnInitializedAsync()
{
    if (HttpContext.User.Identity?.IsAuthenticated == true)
    {
        NavigationManager.NavigateTo("/");
        await base.OnInitializedAsync();
    }
}

divvjson avatar Feb 24 '24 16:02 divvjson

@davidjohanssson thanks for contacting us.

That exception is thrown and caught by the framework and is used to signal navigation internally. The only reason you are observing it is because you have enabled breaking on first chance exceptions in the debugger.

javiercn avatar Feb 26 '24 11:02 javiercn