middlewareasp.net-core-6.0document-root

How to create custom StaticFileMiddleware and redirect request to needed folder


My site with Asp.Net Core 6 hes custom root folder for static files, different from folders with configuration, folders with Program.cs/vb, folders with View, folders with Area, folders with Controllers.

Parts of static files from this custom root working fine, but other static files don't working.

Custom root for static files

I try to intercept request to static files and manually redirect all request to my root folder with static files.

I write this code for this interception.

    App.Use(Async Function(context, [next])
                Dim CurrentEndpoint = context.GetEndpoint()
                If (CurrentEndpoint Is Nothing) Then
                    Debug.WriteLine($"RequestPath {context.Request.Path} endpoint nothing.")
                    Dim StaticOptions As StaticFileOptions = New StaticFileOptions With {.FileProvider = New PhysicalFileProvider(Builder.Configuration("StaticFilesRoot"))}
                    Dim Opt As IOptions(Of StaticFileOptions) = Options.Create(StaticOptions)
                    Dim StaticMiddleware = New StaticFileMiddleware(
                    Async Function()
                        Await [next](context)
                    End Function,
                    Environment,
                    Opt.Value,
                    LoggerFactory)
                Else
                    Await [next](context)
                End If
            End Function)

But my attempt to intercept "wrong" request and manually redirect it to needed folder is failed. Because I maybe made mistake to create StaticFileMiddleware.

 Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request starting HTTP/2 GET https://localhost:7168/scripts/script.js - -
 RequestPath /scripts/script.js endpoint nothing.
 Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware: Error: An unhandled exception has occurred while executing the request.
 System.InvalidCastException: Unable to cast object of type 'Microsoft.AspNetCore.Builder.StaticFileOptions' to type 'Microsoft.Extensions.Options.IOptions`1[Microsoft.AspNetCore.Builder.StaticFileOptions]'.
    at FrontEnd.Program._Closure$__12-0._Lambda$__10(HttpContext context, RequestDelegate next) in G:\Projects\CryptoChestMax\FrontEnd\FrontEndCode\Program.vb:line 256
    at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
    at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
    at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

Unfortunately, I can not understand what I doing wrong and what cast is not valid. If I try to create custom middleWare in debugger than there are not error, but attempt to processing request with my new StaticMiddleware get me error.

New options

What wrong in my StaticMiddleware?


Solution

  • In current question this is my mistake with Root for StaticHtmlFiles, but my way to detection error can be helpful to any programmer.

    I have create this Route Analyzer and finally understand that I have wrong variables loaded as Root for static files.

        'Route anylizer
        App.Use(Async Function(context As HttpContext, NextRequestDelegate As RequestDelegate)
                    Dim CurrentEndpoint = context.GetEndpoint()
                    If (CurrentEndpoint Is Nothing) Then
                        Debug.WriteLine($"RequestPath {context.Request.Path} endpoint nothing.")
                        Dim StaticOptions As StaticFileOptions = New StaticFileOptions With {.FileProvider = New PhysicalFileProvider(Builder.Configuration("StaticFilesRoot"))}
                        Dim Opt As IOptions(Of StaticFileOptions) = Options.Create(StaticOptions)
                        Dim NewEnvironment As IWebHostEnvironment = Environment
                        NewEnvironment.ContentRootPath = Builder.Configuration("StaticFilesRoot")
                        NewEnvironment.WebRootPath = Builder.Configuration("StaticFilesRoot")
                        Dim StaticMiddleware = New StaticFileMiddleware(
                            Async Function()
                                'Await NextRequestDelegate(context)
                                Dim StaticFile As IFileInfo = Opt.Value.FileProvider.GetFileInfo(context.Request.Path)
                                If Not StaticFile.Exists Then
                                    Await context.Response.WriteAsync("File is nothing")
                                Else
                                    Await context.Response.SendFileAsync(StaticFile)
                                End If
    
                            End Function,
                            NewEnvironment,
                            Opt,
                            LoggerFactory)
                        Await StaticMiddleware.Invoke(context)
                    Else
                        Debug.WriteLine($"Endpoint: {CurrentEndpoint.DisplayName}")
                        Dim Endpoint As RouteEndpoint = TryCast(CurrentEndpoint, RouteEndpoint)
                        Debug.WriteLine($"RoutePattern: {Endpoint?.RoutePattern.RawText}")
                        For j As Integer = 0 To CurrentEndpoint.Metadata.Count - 1
                            Debug.WriteLine($"Endpoint Metadata {j}: {CurrentEndpoint.Metadata(j)}")
                        Next
                        Await NextRequestDelegate(context)
                    End If
                End Function)
    

    Is static file present in custom root?

    And anybody can create custom message, custom code or custom header for missing files by this way

    custom response for missing files