3

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

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

我可以编写自己的 StaticFileHandler 来提供带有 Cache-Control: public 和到期日期的 VPP 内容。

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

4

2 回答 2

5

我弄清楚为什么会发生这种情况。我查看了 StaticFileHandler 的源代码。对于嵌入文件,它不设置任何缓存头。它仅适用于文件系统中的文件。这意味着这永远不会正常工作。

你有两个选择。

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

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

祝你好运。

于 2013-04-30T19:20:45.967 回答
3

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

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

在此处输入图像描述

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

特别感谢评论员:)

于 2016-05-05T16:06:04.193 回答