Download and Show Private Azure Blob with ASP MVC

I am using ASP MVC 5 Razor with Microsoft Azure Blob storage. I can successfully upload documents and images to Blob storage using MVC, but I am struggling to find some MVC examples for uploading and displaying files.

It would be pretty easy to do this if the blobs were saved as public files, but I need them to be private.

Can anyone give me any examples or guidelines on how to do this?

I have the code below that seems to be fetching the Blob, but I'm not sure what to do with it in MVC in order to render it in the browser.

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


source to share


3 answers


I am making an assumption based on your comment

It would be pretty easy to do this if the blobs were saved as public files, but I need them to be private

because the blobs are private, you are trying to return the byte array to the client using the mvc controller.

However, an alternative method would be to use the SharedAccessSignature to provide the client with temporary access to the blob, which can then be accessed as a shared URL. The period for which the URL is valid can be specified in your controller. This also has the advantage that you remove the download from your controller, as the client will download the file directly from the repository.



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

      

Then in your view you can use the viewmodel value

//image
<img src="@Model.FileUrl" />
//in a new tab
<a href="@Model.FileUrl" target="_blank">`Open in new window`</a>

      

+12


source


I hope this answers your questions:

To upload a file or open it in a new window / tab, you need to specify the correct Content-Disposition in the header. Here's an example here . Basically, if you want to download a blob, you do the following. Be aware that if the mime type is set to application / octet-stream, the file will not open in a new tab. It will be loaded. You need to set the correct ContentType when you save the blob to Azure.

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

      

To open the file in a new tab, make sure you specify the target in the view:



<a href="UrlToControllerAction" target="_blank"></a>

      

As for the blob being public / private, you must handle it when interacting with Azure Storage. If you want to give users permission to access your blocks from outside your application, you must use a shared signature. Details here.

Hope this helps.

+2


source


As adding Alex S's excellent answer, if you are just adding a Download button or hyperlink, an alternative approach is to have the method MyControllerAction

return Redirect:

return Redirect(newUri.ToString());

      

And then you think the download link will open the response from that controller action in a new window:

<a href="@Url.Action("MyControllerAction", "MyController", new { fileName = fileName})" target="_blank">Download</a>

      

This will download the file to the user and without starting navigation to the new page.

0


source







All Articles