asp.netrazorblazorhttp-status-code-404router

Blazor Server: Custom 404 component causes RenderFragment<T> error with InteractiveServer render mode


I'm trying to use a custom 404 component in a Blazor Server app with this router setup:

<Router AppAssembly="@typeof(App).Assembly" @rendermode="InteractiveServer">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="typeof(MainLayout)" />
    </Found>
    <NotFound>
        <LayoutView Layout="typeof(MainLayout)">
            <NotFoundComponent />
        </LayoutView>
    </NotFound>
</Router>

However, when I run the app, I get the following error:

An unhandled exception occurred while processing the request.
InvalidOperationException: Cannot pass RenderFragment<T> parameter 'Found' to component 'Router' with rendermode 'InteractiveServerRenderMode'. Templated content can't be passed across a rendermode boundary, because it is arbitrary code and cannot be serialized.

Microsoft.AspNetCore.Components.Endpoints.SSRRenderModeBoundary.ValidateParameters(IReadOnlyDictionary<string, object> latestParameters)

It seems like the @rendermode="InteractiveServer" is causing the Found template to fail. I want to display a custom 404 component, but it doesn't work with this global render mode.

Question:

How can I use a custom 404 component (NotFoundComponent) in a Blazor Server app without getting the RenderFragment<T> serialization error? Is there a different approach for defining the router or render mode that supports custom templates?

Note: working in .net9.0


Solution

  • I've fixed with the following:

    Added app.UseStatusCodePagesWithRedirects("/error-page/{0}"); to the Program.cs.

    Added the page CustomErrorPage.razor with the following content:

    @page "/error-page/{StatusCode:int}"
    
    <div>content</div>
    
    @code {
        [Parameter]
        public int StatusCode { get; set; }
    
        public bool Is404 => StatusCode == 404;
        public string Heading => Is404 ? "Page not found 404" : $"Error {StatusCode}";
    }