我在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);
}
我在这里遗漏了什么 - 为什么我不能在这里删除异步选项。另外,我是否完全错过了为什么文件下载损坏?
答案 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);
}