Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom Middleware is causing Blazor Server-side page to stop working

My custom middleware appears to be causing some sort of conflict with my blazor server-side page. The sample middleware in short checks for a bool status and if true redirects to the counter page provided by the out of the box blazor template. Without the middleware inserted into the pipeline the counter page works just fine when you click the button, but once the middleware is placed in the pipeline the button no longer works, as it does not increment the count. I've placed the custom middleware right before the app.UseEndpoints middleware, though it appears it doesn't matter where it's placed, as it doesn't work no matter the order that it's in. Why is my custom middleware breaking the blazor server-side page from functioning properly?

middleware:

class CheckMaintenanceStatusMiddleware
{
    private readonly RequestDelegate _next;
    public CheckMaintenanceStatusMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {


        var statusCheck = true;

        if(statusCheck && context.Request.Path.Value != "/counter")
        {
            context.Response.Redirect("/counter");
        }
        else
        {
            await _next.Invoke(context);
        }
    }

}

public static class CheckMaintenanceStatusMiddlewareExtension
{
    public static IApplicationBuilder UseCheckMaintenanceStatus(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<CheckMaintenanceStatusMiddleware>();
    }
}

configure method in Startup file:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{


    var connectionString = Configuration.GetConnectionString("DefaultConnection");
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        // 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.UseHttpsRedirection();

    app.UseStaticFiles();


    app.UseCookiePolicy();

    app.UseRouting();

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

    app.UseCheckMaintenanceStatus();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        endpoints.MapBlazorHub();
        endpoints.MapFallbackToPage("/_Host");
    });

}
like image 883
user1206480 Avatar asked Oct 19 '19 17:10

user1206480


People also ask

What is middleware in Blazor?

Middleware is handlers that are arranged into a pipeline to handle requests and responses. In a Web Forms app, HTTP handlers and modules solve similar problems. In ASP.NET Core, modules, handlers, Global. asax. cs, and the app life cycle are replaced with middleware.

How do you handle errors in Blazor?

When an error occurs, Blazor apps display a light yellow bar at the bottom of the screen: During development, the bar directs you to the browser console, where you can see the exception. In production, the bar notifies the user that an error has occurred and recommends refreshing the browser.

Can I use MVC in Blazor?

Blazor applications are component-based. Blazor components can be used in existing ASP.NET MVC applications.

Should I use Blazor server or Blazor Wasm?

The Blazor Server hosting model offers several benefits: Download size is significantly smaller than a Blazor WebAssembly app, and the app loads much faster. -The app takes full advantage of server capabilities, including the use of . NET Core APIs.


2 Answers

With your code , the blazor negotiate url is also been redirect so negotiate won't work .

Try below codes which avoid that :

if (statusCheck && context.Request.Path.Value != "/counter"&& !context.Request.Path.Value.StartsWith("/_blazor"))
{
    context.Response.Redirect("/counter");
}
else
{
    await _next.Invoke(context);
}
like image 111
Nan Yu Avatar answered Oct 23 '22 17:10

Nan Yu


I suspect what's happening here is

  • The browser goes to the app URL and attempts to negotiate a SignalR connection.
  • SignalR returns the protocol and token to use to successfully connect to the Hub (using "/_blazor?id=token_value").

Unfortunately the custom middleware is redirecting every request, so it ends up stopping the application from doing the initial connection to the hub (triggering a bunch of console errors) - though I was able to successfully redirect to "/counter". But because the middleware is stopping the SignalR connection, it breaks the connection from the client to the server which is necessary for Blazor Server apps.

I would suggest moving this check from middleware. You could try creating a service that can return if the app is in maintenance mode, add a service call to the Index.razor component, and then render a "Maintenance Mode" component if necessary.

like image 24
Corey Weathers Avatar answered Oct 23 '22 17:10

Corey Weathers