'Change the headers of static files in Asp.net Core

I am using package Microsoft.AspNet.StaticFiles and configuring it in Startup.cs as app.UseStaticFiles(). How can I change the headers of the delivered files ? I want to set cache expiry etc for images, css and js.



Solution 1:[1]

You can use StaticFileOptions, which contains an event handler that is called on each request of a static file.

Your Startup.cs should look something like this:

// Add static files to the request pipeline.
app.UseStaticFiles(new StaticFileOptions()
{
    OnPrepareResponse = (context) =>
    {
        // Disable caching of all static files.
        context.Context.Response.Headers["Cache-Control"] = "no-cache, no-store";
        context.Context.Response.Headers["Pragma"] = "no-cache";
        context.Context.Response.Headers["Expires"] = "-1";
    }
});

You can, of course, modify the above code to check the content type and only modify headers for JS or CSS or whatever you want.

Solution 2:[2]

Based on Josh Mouch's answer above, added code to determine if it's a pdf file

Startup.cs:

      app.UseStaticFiles(new StaticFileOptions
      {
        OnPrepareResponse = ctx =>
          {
            if(ctx.File.Name.ToLower().EndsWith(".pdf"))
            {
              ctx.Context.Response.Headers.Append("Cache-Control", "public,max-age=86400");
            }
            else
            {
              ctx.Context.Response.Headers.Append("Cache-Control", "public,max-age=31104000");
            }
          }
      });

Solution 3:[3]

If you're looking for a solution allowing you to configure different behaviours for each environment (development, production & more), which is also the point of having these settings in the web.config file instead of hard-coding the whole stuff, you could consider the following approach.

Add the following key/value section in the appsettings.json file:

  "StaticFiles": {
    "Headers": {
      "Cache-Control": "no-cache, no-store",
      "Pragma": "no-cache",
      "Expires": "-1"
    }
  }

Then add the following in the Startup.cs file's Configure method accordingly:

app.UseStaticFiles(new StaticFileOptions()
{
    OnPrepareResponse = (context) =>
    {
        // Disable caching for all static files.
        context.Context.Response.Headers["Cache-Control"] = Configuration["StaticFiles:Headers:Cache-Control"];
        context.Context.Response.Headers["Pragma"] = Configuration["StaticFiles:Headers:Pragma"];
        context.Context.Response.Headers["Expires"] = Configuration["StaticFiles:Headers:Expires"];
    }
});

This will allow the developer to define different cache settings using different/multiple/cascading settings files (appsettings.json, appsettings.production.json and so on) - which is something that could be done with the old web.config configuration pattern - with the ASP.NET Core's new one.

For additional info regarding the topic I also suggest to read this post on my blog and/or these great articles from the official ASP.NET Core docs:

Solution 4:[4]

You have to write a middleware to do this, I've a sample that remove headers on my github https://github.com/aguacongas/chatle
Look at the ChatLe.HttpUtility project, it's a bit tricky. you can take a look of this question as well:

How to do remove some httpresponse headers on each response like Server and ETag?

However this will not work under IIS, because IIS manage statics files itself. It will work only on stand-alone application like kestrel or firefly

Solution 5:[5]

Under IIS, you can add a web.config file to your wwwroot folder with header configurations. An example that will control cache headers for all files:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>

    <!-- Disable caching -->
    <httpProtocol>
      <customHeaders>
        <add name="Cache-Control" value="no-cache" />
      </customHeaders>
    </httpProtocol>

  </system.webServer>
</configuration>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Matt Lengenfelder
Solution 3
Solution 4 Community
Solution 5 Malgaur