17

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.

1

5 Answers 5

27

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Since these are static files as .css/.js, usually you should use an appropriate time for cache instead of "no-cache, no-store" to increase performance, eg: context.Context.Response.Headers [HeaderNames.CacheControl] = "public, max-age=86400"; (86400 here is 24 hour = 24*60*60 sec). And to force bypass the cache when we update the files, We can also use asp-append-version="true" tag helper beside the <link>, <script> ... tags to add some auto generated query string based on hash of the files which will be auto-updated.
8

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");
            }
          }
      });

Comments

6

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:

Comments

2

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

1 Comment

Do you mean all three of those won't work under IIS? Or one of the answers, specifically?
1

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>

1 Comment

That won't work if the websites host .NET Core modules (like in case of OP), as .NET Core doesn't honour web.config. The way .NET Core works is essentially running their own web server called Kestrel, which is hiding behind IIS + HTTP Module (aka ANCM, aka ASP.NET Core Module). learn.microsoft.com/en-us/aspnet/core/fundamentals/servers/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.