2011-05-13 134 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并显示路径在前端消息,该文件已被下载的位置[...]

相关问题