我有一个可重用的部分视图,脚本和图像库,它们嵌入在程序集中并在项目之间共享。
一切正常,我修改了web.config以使System.Web.StaticFileHandler提供所有必需的文件类型,但遗憾的是,它使用Cache-Control服务所有资源:private。
我可以编写自己的StaticFileHandler,它可以使用Cache-Control提供VPP内容:公共和过期日期。
如何使用VirtualPathProvider.GetCacheDependency实现缓存支持?
答案 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
并添加所需的电子标签标题,以便它应该保留在缓存中,除非该程序集已更改:
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();
}
}