2011-05-13 117 views
5

我有一個運行在azure中的MVC網絡應用程序,可以提供存儲在雲存儲中的大文件,如mp3,pdf等等。什麼是提供這些文件的最佳方式,因此用戶在點擊鏈接/按鈕時可以下載它們?從Azure雲存儲下載大文件的最佳方式

簡單的方法是隻是告訴他們:

<a href="...blob.core.windows.net/container/file.mp3">

但隨後用戶必須右鍵點擊下載。

強制進行下載,您可以返回一個文件的ActionResult:

public ActionResult GetPDF(string filename) 
{ 
    return File(filename, "application/pdf", Server.HtmlEncode(filename)); 
} 

這樣做的缺點(我認爲)是,webrole在文件並將其輸出流中讀取數據,這將消耗資源,並可能讓許多用戶陷入困境。而簡單的href鏈接解決方案基本上將工作交給工作人員,讓瀏覽器直接與雲存儲進行對話。

我正確嗎?我應該關心卷軸上的額外工作嗎?

是否有另一種方式來強制文件下載而不會增加網絡負擔?

UPDATE:

所以我落得這樣做上傳MP3與內容類型「二進制/八位字節流」 - 這似乎強制下載提示。不知道這是否是一種好的做法,但它迄今爲止工作。

回答

4

你的假設是正確的,如果你想使用的ActionResult你需要先下載文件到Web角色,然後流下來的客戶端。如果你想避免這種情況,特別是對於大文件,並將其留給Azure存儲,因爲那麼Microsoft必須擔心處理請求,如果獲得大量流量,則不必爲更多Web角色付費。

如果您要託管的所有文件都是公開的,但如果要保護這些文件(如果您想要執行此操作,請查看shared access signatures)會有點麻煩。

您是否嘗試過在blob上設置內容類型?根據您將文件上傳到BLOB存儲的方式,可能不會設置它們。如果您通過自己的代碼上傳斑點,您可以通過CloudBlob.Attributes.Properties.ContentTypeMSDN

+0

謝謝。是的,內容類型設置正確(音頻/ mpeg),並且當您單擊它在瀏覽器中播放的鏈接時。我希望有一種方法可以在不通過網頁的情況下啓動下載。似乎應該可以用javascript來實現?你只是想告訴瀏覽器下載而不是播放它。 – PeteShack 2011-05-13 14:46:25

+0

我發現缺少一部分難題,從blob存儲下載時,它沒有將Content-disposition頭設置爲附件,因此瀏覽器不知道您想將其視爲下載而不是隻需要做一些事情(我想你可以在Azure的預發佈版本中進行設置)。對Blob和Content-disposition的簡單搜索將爲您提供大量有關如何在MVC之外完成這些任務的示例。我懷疑這是所有的文件操作結果。 – knightpfhor 2011-05-18 04:45:23

0

訪問此代碼我已經開發了一個ActionResult,用於從存儲中獲取文件,但我沒有將其輸出到流中,返回下載的文件,我可以得到幫助,請我這動作代碼: 公衆的ActionResult GetPDF(字符串文件名) {

var storageAccountName = this.User.StorageAccountName; 
     var storageAccountKey = this.User.StorageAccountKey; 
     string connectionString = string.Format(
        "DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}", 
        storageAccountName, storageAccountKey); 

     //Extraction de votre chaîne de connexion par programme 
     CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString); 

     //Create a CloudFileClient object for credentialed access to File storage. 
     CloudFileClient fileClient = storageAccount.CreateCloudFileClient(); 

     //Get a reference to the file share . create a share folder take the name of CompanyCode 
     CloudFileShare share = fileClient.GetShareReference(this.User.CompanyCode); 

     share.CreateIfNotExists(); 
     byte[] fileBytes = null; 
     // create if not Exist 
     if (share.Exists()) 
     { 
      // string StoragePath = "/Uploads/Locations/" + LocationToAdd.Id.ToString(); 

      CloudFileDirectory rootDirectory = share.GetRootDirectoryReference(); 
      CloudFileDirectory topDirectory = rootDirectory.GetDirectoryReference("Uploads"); 
      topDirectory.CreateIfNotExistsAsync(); 
      CloudFileDirectory midDirectory = topDirectory.GetDirectoryReference("Locations"); 
      midDirectory.CreateIfNotExistsAsync(); 
      CloudFileDirectory sampleDir = midDirectory.GetDirectoryReference(document1.LocationId.ToString()); 
      sampleDir.CreateIfNotExistsAsync(); 
      //Get a reference to the file we created previously. 
      CloudFile file = sampleDir.GetFileReference(filename); 

      if (file.Exists()) 
      { 
       //Write the contents of the file to the console window. 
       // string fileresult = file.DownloadTextAsync().Result; 
       // file.DownloadToByteArray(fileBytes, 1, null, null, null); 

       string outputFileName = Path.GetTempFileName(); 
       if (System.IO.File.Exists(outputFileName)) 
       { 
        System.IO.File.Delete(outputFileName); 
       } 
       OperationContext context = new OperationContext(); 
       file.DownloadToFileAsync(outputFileName, FileMode.CreateNew, null, null, context); 

       // what should i do after this ........ 
      } 
      } 
      } 
} 
1

您可以返回包含其中文件的下載路徑outputFileName並顯示路徑在前端消息,該文件已被下載的位置[...]

相關問題