2015-06-17 38 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

相關問題