Search code examples
asp.net-corestatic-files

ASP.net Core Static Files - How to return a default file (per extension) if the one requested doesn't exist?


I understand how to set up serving static files on an ASP.net Core web application, per this official guide. I don't want to return a default.html page if the image (for example) they're requesting for doesn't exist.

In Startup.cs's Configure(IApplicationBuilder app, IHostingEnvironment env);, I have app.UseStaticFiles().

My Program.cs file:

public class Program
{
    public static void Main(string[] args)
    {
        BuildWebHost(args).Run();
    }

    public static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .UseDefaultServiceProvider(options =>
                options.ValidateScopes = false)
            .Build();
}

Which will, by default, allow me to store to and serve files from that wwwroot folder in my application.

If I have the image file mypic.jpg in wwwroot, I can open my browser and go to http://localhost:53020/mypic.jpg to view it.

Suppose I already deployed this app and someone were to go to their browser and go to, or in their web page, set an img's src equal to http://mydeployedsite.com/nonexistentpic.jpg, They would get a 404, or a default page, depending on which one I chose. However, I want to serve an image whose graphic indicates "file not found", instead. I don't see anywhere in that guide I linked that gives me an option to serve default files, per extension, if the one requested doesn't exist.

I will probably have to write middleware for what I want. I understand how to write basic middleware, but in such a middleware, I don't know how to intercept a 404 response that came from the static files middleware. Or, there may be more options in the static files middleware not included in that official document. What other approaches can I take besides serving files via routes and controller functions?


Solution

  • There are no options in static files middleware to achieve your requirement.
    I think you could intercept 404 response, and check whether the request is request for a image. Here is a simple code

            app.Use(async (context, next) => {
                await next.Invoke();
                //handle response
                //you may also need to check the request path to check whether it requests image
                if(context.Response.StatusCode == 404 && context.Request.Path.Value.Contains(".jpg"))
                {
                    context.Response.Redirect("/DefaultImage.gif"); //path in wwwroot for default image
                }
            });
            app.UseStaticFiles();