我使用ASP MVC 5 Razor和Microsoft Azure Blob存储。我可以使用MVC成功地将文档和图像上传到Blob存储,但我很难找到一些MVC示例如何下载和显示文件。
如果将blob存储为公共文件,那么执行此操作将非常简单,但我需要它们是私有的。
任何人都可以给我任何示例或指导如何实现这一目标吗?
我在下面有一些似乎检索Blob的代码,但我不知道如何在MVC中用它来实际在浏览器中显示它。
var fullFileName = "file1.pdf";
var containerName = "default";
// Retrieve storage account from connection string.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["AttachmentStorageConnection"].ConnectionString);
// Create the blob client.
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
// Retrieve reference to a previously created container.
CloudBlobContainer container = blobClient.GetContainerReference(containerName);
// Retrieve reference to a blob ie "picture.jpg".
CloudBlockBlob blockBlob = container.GetBlockBlobReference(fullFileName);
答案 0 :(得分:13)
我根据你的评论作出假设
如果存储blob,那么执行此操作将非常简单 作为公共文件,但我需要它们是私人的
因为blob是私有的,所以你试图通过mvc控制器将一个字节数组返回给客户端。
但是,另一种方法是使用SharedAccessSignature为客户端提供对blob的临时访问权限,然后您可以将其作为公共URL访问。可以在控制器中指定URL有效的时间段。由于客户端将直接从存储中下载文件,因此还具有从控制器带走负载的优势。
// view model
public class MyViewModel
{
string FileUrl {get; set;}
}
// controller
public ActionResult MyControllerAction
{
var readPolicy = new SharedAccessBlobPolicy()
{
Permissions = SharedAccessBlobPermissions.Read,
SharedAccessExpiryTime = DateTime.UtcNow + TimeSpan.FromMinutes(5)
};
// Your code ------
// Retrieve storage account from connection string.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings ["AttachmentStorageConnection"].ConnectionString);
// Create the blob client.
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
// Retrieve reference to a previously created container.
CloudBlobContainer container = blobClient.GetContainerReference(containerName);
// Retrieve reference to a blob ie "picture.jpg".
CloudBlockBlob blockBlob = container.GetBlockBlobReference(fullFileName);
//------
var newUri = new Uri(blockBlob.Uri.AbsoluteUri + blockBlob.GetSharedAccessSignature(readPolicy));
var viewModel = new MyViewModel()
{
FileUrl = newUri.ToString()
};
return View("MyViewName", viewModel);
}
然后在您的视图中,您可以使用视图模型值
//image
<img src="@Model.FileUrl" />
//in a new tab
<a href="@Model.FileUrl" target="_blank">`Open in new window`</a>
答案 1 :(得分:2)
我希望这能回答你的问题:
要下载文件或在新窗口/选项卡中打开它,您需要在标题中指定正确的Content-Disposition。有一个例子here。基本上,如果要下载blob,请执行以下操作。请记住,如果将mime类型设置为application / octet-stream,则不会在新选项卡中打开该文件。它将被下载。在Azure中保存blob时,需要设置正确的ContentType。
//Downloads file
public ActionResult Index(string name)
{
Response.AddHeader("Content-Disposition", "attachment; filename=" + name);
var blob = _azureBlobContainer.DownloadData(); //Code that returns CloudBlockBlob
var memStream = new MemoryStream();
blob.DownloadToStream(memStream);
return File(memStream.ToArray(), blob.Properties.ContentType);
}
//Opens file if correct ContentType is passed
public ActionResult Index(string name)
{
Response.AddHeader("Content-Disposition", "inline; filename=" + name); //Set it as inline instead of attached.
var blob = _azureBlobContainer.DownloadData(); //Code that returns CloudBlockBlob
var memStream = new MemoryStream();
blob.DownloadToStream(memStream);
return File(memStream.ToArray(), blob.Properties.ContentType);
}
要在新标签页中打开文件,请确保在视图中指定目标:
<a href="UrlToControllerAction" target="_blank"></a>
关于blob是public / private,您应该在与Azure Storage的交互中处理它。如果要授予用户从应用程序外部访问blob的权限,则应使用共享访问签名。 Details here.
希望这会有所帮助。
答案 2 :(得分:0)
作为Alex S的优秀答案,如果您只是添加说“下载”和“#39;按钮或超链接然后另一种方法是使MyControllerAction
方法返回重定向:
return Redirect(newUri.ToString());
然后在您的视图中,使下载链接在新窗口中打开来自该控制器操作的响应:
<a href="@Url.Action("MyControllerAction", "MyController", new { fileName = fileName})" target="_blank">Download</a>
这将触发将文件下载到用户,而不会触发导航到新页面。