Search code examples
c#blazormiddlewareblazor-server-side

Blazor Server: NavigationManager in Middleware


I'm trying to create a httphandler in a Blazor Server app that handles all unsuccessful status codes. If a 401 is thrown, I want to redirect to a custom 401 page.

For some reason, I cannot get the NavigationManager to work after depency injection. It looks like it does load the NavigationManager, but it never initializes it.

public class RichardsHandler : DelegatingHandler
{
    protected readonly NavigationManager _navManager;
    public RichardsHandler(NavigationManager navigationManager)
    {
        _navManager = navigationManager;
    }
    protected override async Task<HttpResponseMessage> SendAsync(
    HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var response = await base.SendAsync(request, cancellationToken);

        _navManager.NavigateTo("/401");

        return response;
    }
}

I simply put the NavigateTo there to try and navigate to another page, but I always get a "InvalidOperationException: 'RemoteNavigationManager' has not been initialized" exception.

Again, this is a Blazor Serverside app. Am I overlooking something or is this by design in the NavigationManager?


Solution

  • Middleware will only be called on the initial load of the Application. After that everything is handled in-page by the various bits of code that make up the navigation manager pipeline and by router component: there are no calls back to the server and therefore no middleware invoked.

    NavigationManager is a DI service that receives data from the Blazor client side code running in the browser whenever a browser side navigation event occurs. You can't access it directly from middleware because it only exists in the Blazor Hub session on the server.

    If you want to show a specific component or markup on page not found and unauthorized requests, code it into App.razor.