3
votes

I am currently testing out an asp.net core 3 blazor server-side app. I built a middleware extension in f#, and called it from c# within the Configure method of the Startup class. It appears to initially attempt the redirect as the correct url is called, but I get an error page stating that the page isn't redirecting properly. What am I missing here.

F#:

type CheckMaintenanceStatusMiddleWare(next : RequestDelegate) =

    let _next = next

    member this.InvokeAsync(context : HttpContext) =

        let statusCheck = true
        if statusCheck
        then 
            Task.Run(fun arg -> context.Response.Redirect("/Maintenance"))
        else 
           _next.Invoke(context)

[<Extension>]
type CheckMaintenanceStatusMiddleWareExtensions() =

    [<Extension>]
    static member inline UseCheckMaintenanceStatus(builder : IApplicationBuilder) =

        builder.UseMiddleware<CheckMaintenanceStatusMiddleWare>() 

C#

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseCheckMaintenanceStatus();

            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.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
                endpoints.MapBlazorHub();
                endpoints.MapFallbackToPage("/_Host");
            });
        }

Razor Component:

@page "/Maintenance"

<h3>Maintenance</h3>

@code {

}
1
Seems that your code makes the browser redirect all the time? - itminus
If that's the case, please check whether current path is /Maintenance to avoid redirect-loop: if statusCheck && context.Request.Path.Value <> "/Maintenance" then - itminus
Note that you don’t need let _next = next, you can use next directly. Also, creating Tasks by scheduling on the threadpool is costly (for various reasons), consider using Task.FromResult - CaringDev
@itminus Your suggestion worked. Can you submit this as an answer so that I may accept it. Also can your provide an explanation within in your answer as to how the loop is created in this situation. - user1206480
@CaringDev Can you explain a bit in more detail how to do this. I haven't seen any examples of this in the documentation for middleware construction, and in regards to my if statement I was just trying be consistent with next.Invoke in which returns type Task. - user1206480

1 Answers

3
votes

A redirect-loop might happens as below:

                                              (redirect-loop might happens)
Request Process Starts                       <---------------------------+
 |----->  CheckMaintenanceStatusMiddleWare                               |
              (check status)                                             |
                  if fail then redirect to '/Maintenance' -------------->|
                  else 
                       |----> go to inner middlewares by next(context)

To avoid the endless redirect loop, check whether the current path has already been changed to /Maintenance:

if statusCheck && context.Request.Path.Value <> "/Maintenance" then
    ... redirect
else
    ... invoke inner middlewares