Mike Dymond
Mike Dymond

Reputation: 1185

How do I set a global rendermode of InteractiveServer and still be able to use UseStatusCodePagesWithReExecute

I want to be able to use UseStatusCodePagesWithReExecute to handle invalid URLs in a Blazor Web App. This works fine until I try to enable InteractiveServer rendermode globally. Then when I navigate to an unknown path it will briefly show the page that UseStatusCodePagesWithReExecute is set to use, but then it just shows a blank with "Not found" displayed.

Steps to reproduce.

  1. Create a new empty Blazor Web App with Interativity set to 'Server'.
  2. Add app.UseStatusCodePagesWithReExecute("/error"); to Program.cs

At this point all works as expected. When you navigate to an unknown path it will show the page referenced in UseStatusCodePagesWithReExecute.

However:

  1. Add @rendermode="new InteractiveServerRenderMode(prerender: false)" to the App.razor page

Now when you navigate to an unknown path it will briefly show the page referenced in UseStatusCodePagesWithReExecute but then just show "Not found".

I have found that the "Not found" text is actually Blazor rendering a non-existent <NotFound> component! If you add a <NotFound> component to the <Routes> component it will render that instead.

Program.cs

using BlazorApp3.Components;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error", createScopeForErrors: true);
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseStatusCodePagesWithReExecute("/error");

app.UseHttpsRedirection();

app.UseStaticFiles();
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="BlazorApp3.styles.css" />
    <HeadOutlet @rendermode="new InteractiveServerRenderMode(prerender: false)" />
</head>
<body>
    <Routes @rendermode="new InteractiveServerRenderMode(prerender: false)" />
    <script src="_framework/blazor.web.js"></script>
</body>

</html>

Routes.razor

<Router AppAssembly="typeof(Program).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)" />
        <FocusOnNavigate RouteData="routeData" Selector="h1" />
    </Found>
    <NotFound>
        <p>Now you see this text!</p>
    </NotFound>
</Router>

Can anyone else reproduce this? Is this expected behaviour? Is it possible to set a global rendermode of InteractiveServer and still use UseStatusCodePagesWithReExecute to handle page not found errors?

Cheers Mike

Upvotes: 0

Views: 26

Answers (0)

Related Questions