从azure storageblob下载时损坏的文件

时间:2017-03-14 16:01:14

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

我在asp.net mvc网站上使用azure存储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);
    }

这是我的新非异步版本,但我在最后一行收到错误 - 无法转换为&#39; system.threading.tasks.task&#39;到&#39;字符串&#39;。

    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);
    }

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

2 个答案:

答案 0 :(得分:0)

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

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

data.Seek(0, SeekOrigin.Begin);

答案 1 :(得分:0)

如果要提供从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);
}