2015-06-17 44 views
0

我写了一个自定义实现VirtualPathProvider,它允许我从Azure Blob存储中提取图像。提供者做它的事情,但在每个请求对性能不太好的时候调用GetFile在自定义VirtualPathProvider中未调用GetCacheDependency

的GetFile

public override VirtualFile GetFile(string virtualPath) 
{ 
    string path = this.FormatVirtualPath(virtualPath); 
    if (!path.StartsWith(this.pathPrefix, StringComparison.InvariantCultureIgnoreCase)) 
    { 
     return base.GetFile(virtualPath); 
    } 

    string fileSystemPath = this.RemovePathPrefix(path); 
    return new FileSystemVirtualFile(
         virtualPath, 
         () => 
         this.fileSystem.Value.OpenFile(fileSystemPath)); 
} 

因为我知道,我认为这将是加了一点缓冲的好主意BLOB的最后修改日期,但我似乎无法得到任何工作。

它周围的阅读看来我需要重写,我这样做的方法GetCacheDependencyGetFileHash如下:

GetCacheDependency

public override CacheDependency GetCacheDependency(string virtualPath, 
            IEnumerable virtualPathDependencies, 
            DateTime utcStart) 
{ 
    string path = this.FormatVirtualPath(virtualPath); 

    if (!path.StartsWith(this.pathPrefix, StringComparison.InvariantCultureIgnoreCase)) 
    { 
     return base.GetCacheDependency(virtualPath, 
             virtualPathDependencies, 
             utcStart); 
    } 

    return new BlobCacheDependency(
           this.fileSystem 
            .Value.GetLastModified(path) 
            .DateTime.ToUniversalTime()); 
} 

GetFileHash

public override string GetFileHash(string virtualPath, IEnumerable virtualPathDependencies) 
{ 
    string path = this.FormatVirtualPath(virtualPath); 
    if (!path.StartsWith(this.pathPrefix, StringComparison.InvariantCultureIgnoreCase)) 
    { 
     return base.GetFileHash(virtualPath, virtualPathDependencies); 
    } 

    byte[] bytes = Encoding.Unicode.GetBytes(virtualPath.ToCharArray()); 

    using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider()) 
    { 
     byte[] hash = md5.ComputeHash(bytes); 

     // Concatenate the hash bytes into one long String. 
     return hash.Aggregate(
      new StringBuilder(32), 
      (sb, b) => sb.Append(b.ToString("X2", 
           CultureInfo.InvariantCulture))) 
      .ToString().ToLowerInvariant(); 
    } 
} 

我也有一个习惯执行。

public class BlobCacheDependency : CacheDependency 
{ 
    public BlobCacheDependency(DateTime lastModifiedUtc) 
    { 
     this.SetUtcLastModified(lastModifiedUtc); 
    } 
} 

不幸的是,这些其他方法在请求图像时都不会被调用。我不确定缺少什么。有任何想法吗?

回答

1

好吧,回答这个问题的方法是在我的VirtualFile实现中的Open()方法中设置响应缓存。这允许浏览器缓存文件。

这是一个有点hacky,但工程。在我的代码中,现在看起来像这样。

public override Stream Open() 
{ 
    // Set the response headers here. It's a bit hacky. 
    HttpCachePolicy cache = HttpContext.Current.Response.Cache; 
    cache.SetCacheability(HttpCacheability.Public); 
    cache.VaryByHeaders["Accept-Encoding"] = true; 

    IFileSystem azureBlobFileSystem = FileSystemProviderManager.Current.GetUnderlyingFileSystemProvider("media"); 
    int maxDays = ((AzureBlobFileSystem)azureBlobFileSystem).FileSystem.MaxDays; 

    cache.SetExpires(DateTime.Now.ToUniversalTime().AddDays(maxDays)); 
    cache.SetMaxAge(new TimeSpan(maxDays, 0, 0, 0)); 
    cache.SetRevalidation(HttpCacheRevalidation.AllCaches); 

    return this.stream(); 
} 

http://forums.asp.net/t/1745003.aspx?VirtualPathProvider+files+do+not+have+cache+control+headers

相关问题