使用ASP MVC下载并显示私有Azure Blob

时间:2015-07-17 15:36:51

标签: asp.net-mvc azure razor azure-storage-blobs

我使用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);

3 个答案:

答案 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>

这将触发将文件下载到用户,而不会触发导航到新页面。