【问题标题】:Corrupted files when downloading from azure storageblob从 azure storageblob 下载时文件损坏
【发布时间】:2017-08-05 01:49:39
【问题描述】:

我在 asp.net mvc 站点中使用 azure storage blob 已经有一段时间了。最近,我开始遇到下载后文件损坏的问题。如果我直接从 azure 下载,该文件仍然有效。我只能找到一些与从 azure 异步下载问题相关的注释。请记住,这个问题似乎只与某些文件有关??

这是我以前的下载方法。

    public async Task<ActionResult> Download(int id)
    {
        var file = await db.O_File.SingleAsync(x => x.Id == id);
        var data = await _storage.Download(file.FileName);
        return File(data, "application/octet-stream", file.DisplayFileName);
    }

这是我的新非异步版本,但是我在最后一行遇到错误 - 无法从“system.threading.tasks.task”转换为“string”。

    public ActionResult Download(int id)
    {
        var file = db.O_File.Single(x => x.Id == id);
        var data = _storage.Download(file.FileName);
        return File(data, "application/octet-stream", file.DisplayFileName);
    }

我在这里遗漏了什么 - 为什么我不能在这里删除异步选项。此外,我是否完全错过了为什么文件下载损坏的其他内容?

【问题讨论】:

    标签: c# asp.net-mvc azure-blob-storage


    【解决方案1】:

    在您的非异步版本上,如果您的 _storage.Download 方法仍然在其中使用异步方法(例如 Block Blob DownloadToStreamAsync),您可能会收到该错误

    如果您的下载方法将 blob 作为流抓取,请确保在将流发送到浏览器之前重置流:

    data.Seek(0, SeekOrigin.Begin);
    

    【讨论】:

      【解决方案2】:

      如果您想提供一种从 Azure 存储下载文件的方式。您可以使用 SAS 密钥生成文件链接,并让客户端直接从 Azure 存储下载此文件。它将减少您的 Web 服务器的工作量并提高响应速度。这是使用 SAS 令牌生成 blob URL 的代码。

      public string GetBlobSasUri(string containerName, string blobName, string connectionstring)
      {
          CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionstring);
          CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
          var container = blobClient.GetContainerReference(containerName);
          CloudBlockBlob blockBlob = container.GetBlockBlobReference(blobName);
      
          //Set the expiry time and permissions for the blob.
          //In this case no start time is specified, so the shared access signature becomes valid immediately.
          SharedAccessBlobPolicy sasConstraints = new SharedAccessBlobPolicy();
          sasConstraints.SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(10);
          sasConstraints.Permissions = SharedAccessBlobPermissions.Read;
      
          //Generate the shared access signature on the blob, setting the constraints directly on the signature.
          string sasContainerToken = blockBlob.GetSharedAccessSignature(sasConstraints);
      
          //Return the URI string for the blob, including the SAS token.
          return blockBlob.Uri + sasContainerToken;
      }
      

      在您的网络应用程序中,您只需重定向到前面步骤中获取的 URL。

      public ActionResult  Download()
      {
          string blobURL = GetBlobSasUri("blob name","container name", "connection string");
          return Redirect(blobURL);
      }
      

      【讨论】:

        猜你喜欢
        • 2015-07-14
        • 1970-01-01
        • 1970-01-01
        • 2014-09-01
        • 1970-01-01
        • 2017-08-08
        • 1970-01-01
        • 2015-07-16
        • 2017-12-04
        相关资源
        最近更新 更多