StaticFileHandler,支持缓存VirtualPathProvider提供的内容

时间:2013-03-30 03:06:01

标签: asp.net asp.net-mvc

我有一个可重用的部分视图,脚本和图像库,它们嵌入在程序集中并在项目之间共享。

一切正常,我修改了web.config以使System.Web.StaticFileHandler提供所有必需的文件类型,但遗憾的是,它使用Cache-Control服务所有资源:private。

我可以编写自己的StaticFileHandler,它可以使用Cache-Control提供VPP内容:公共和过期日期。

如何使用VirtualPathProvider.GetCacheDependency实现缓存支持?

2 个答案:

答案 0 :(得分:5)

我弄清楚为什么会这样。我查看了StaticFileHandler的源代码。对于嵌入式文件,它不会设置任何缓存标头。它仅适用于文件系统中的文件。这意味着这将无法正常工作。

您有两种选择。

1.找到另一个http处理程序。我从未使用过这个,但我的搜索出现了:https://code.google.com/p/talifun-web/wiki/StaticFileHandler

2.创建一个http模块,检查是否使用了静态文件处理程序,如果是,则设置缓存详细信息。

祝你好运。

答案 1 :(得分:3)

根据我的研究,我发现了一种实现缓存的hacky方法。

在您的VPP实现中,您应该实现自己的VirtualFile类,扩展System.Web.Hosting.VirtualFile基类。如果需要VPP,它只需要一个流来读取文件。在该阶段,您可以注入标头甚至更改资源的可用性。因为之前,如果我从VPP请求一个静态文件,它会带有标题Cache-Control:private。实际上,服务器说:我不关心你的本地缓存,etags等。我决定你是否应该缓存它。下面的代码将其更改为public并添加所需的电子标签标题,以便它应该保留在缓存中,除非该程序集已更改:

enter image description here

class EmbeddedResourceVirtualFile : VirtualFile
{
    readonly EmbeddedResource embedded;

    public EmbeddedResourceVirtualFile(string virtualPath, EmbeddedResource embedded)
        : base(virtualPath)
    {
        this.embedded = embedded;
    }

    public override Stream Open()
    {
        var assemblyLastModified = embedded.AssemblyLastModified;
        var etag = assemblyLastModified.Ticks;
        var response = HttpContext.Current.Response;
        var cache = response.Cache;
        cache.SetCacheability(HttpCacheability.Public);
        cache.SetETag(etag.ToString());
        cache.SetLastModified(assemblyLastModified);
        cache.SetExpires(assemblyLastModified.AddYears(2));
        return embedded.GetStream();
    }
}

Special thanks for the commentor :)