I'm trying to add long cache headers to static .css and .js files using StaticFileOptions
From various SO and other articles, this is how you do it:
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = ctx =>
{
const int durationInSeconds = 60 * 60 * 24;
ctx.Context.Response.Headers[HeaderNames.CacheControl] =
"public,max-age=" + durationInSeconds;
}
});
However, I am using a bunch of static files provided by a RCL. The RCL has a StaticServing.cs class which I have used from this article: Can Razor Class Library pack static files (js, css etc) too?
For the sake of completeness to my question, this class is as follows:
public StaticServing(IHostingEnvironment environment)
{
Environment = environment;
}
public IHostingEnvironment Environment { get; }
public void PostConfigure(string name, StaticFileOptions options)
{
name = name ?? throw new ArgumentNullException(nameof(name));
options = options ?? throw new ArgumentNullException(nameof(options));
// Basic initialization in case the options weren't initialized by any other component
options.ContentTypeProvider = options.ContentTypeProvider ?? new FileExtensionContentTypeProvider();
if (options.FileProvider == null && Environment.WebRootFileProvider == null)
{
throw new InvalidOperationException("Missing FileProvider.");
}
options.FileProvider = options.FileProvider ?? Environment.WebRootFileProvider;
string basePath = "Static";
ManifestEmbeddedFileProvider filesProvider = new ManifestEmbeddedFileProvider(GetType().Assembly, basePath);
options.FileProvider = new CompositeFileProvider(options.FileProvider, filesProvider);
}
}
in the consuming projects startup.cs I have services.ConfigureOptions(typeof(StaticServing));
and the RCL has <GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
and <EmbeddedResource Include="Static\**\*" />
settings.
With this all in place everything works... UNLESS I add the StaticFileOptions
code at the start of the question, in which case, all references to the embedded static files return 404
.
I have tried adding:
FileProvider = env.ContentRootFileProvider
andFileProvider = env.WebRootFileProvider
To the StaticFileOptions
setting, but that isn't working.
The static files middleware can receive its
StaticFileOptions
in one of two ways:UseStaticFiles
.In your problematic scenario, you're (inadvertently) attempting to configure the middleware using both of these approaches. As soon as you add an argument to the
UseStaticFiles
call, you're replacing the framework-provided configuration for the middleware, which includes setup for RCL support.To build on the framework-provided configuration, you can take advantage of the options pattern in
ConfigureServices
:You'll also need to remove the argument being passed to
UseStaticFiles
.