Using StaticFileOptions() breaks embedded static files from Razor Class Library

风格不统一 提交于 2021-01-28 05:43:21

问题


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 and
  • FileProvider = env.WebRootFileProvider

To the StaticFileOptions setting, but that isn't working.


回答1:


The static files middleware can receive its StaticFileOptions in one of two ways:

  1. Implicitly via Dependency Injection.
  2. Explicitly via the call to 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:

services.Configure<StaticFileOptions>(options =>
{
    options.OnPrepareResponse = ctx =>
    {
        const int durationInSeconds = 60 * 60 * 24;
        ctx.Context.Response.Headers[HeaderNames.CacheControl] =
            "public, max-age=" + durationInSeconds;
    }  
});

You'll also need to remove the argument being passed to UseStaticFiles.



来源:https://stackoverflow.com/questions/63090129/using-staticfileoptions-breaks-embedded-static-files-from-razor-class-library

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!