How to download files from Azure Blob Storage with a Download Link

Viewed 40479

I made an Azure Cloud Service, where you can upload and delete files to the cloud storage using Blobs. I wrote sucessfully a method where you can delete the uploaded blobs from the cloud service:

 public string DeleteImage(string Name)
    {
        Uri uri = new Uri(Name);
        string filename = System.IO.Path.GetFileName(uri.LocalPath);

        CloudBlobContainer blobContainer = _blobStorageService.GetCloudBlobContainer();
        CloudBlockBlob blob = blobContainer.GetBlockBlobReference(filename);

        blob.Delete();

        return "File Deleted";
    }
}

Here is also the code for View with HTML:

@{
ViewBag.Title = "Upload";
}

<h2>Upload Image</h2>

<p>
@using (Html.BeginForm("Upload", "Home", FormMethod.Post, new { enctype = 
"multipart/form-data" }))
{
    <input type="file" name="image"/>
    <input type="submit" value="upload" />
}

</p>

<ul style="list-style-position:Outside;padding:0;">
@foreach (var item in Model)
{
<li>
    <img src="@item" alt="image here" width="100" height="100" />
    <a id="@item" href="#" onclick="deleteImage ('@item');">Delete</a>

</li>
}
</ul>

<script>
function deleteImage(item) {
    var url = "/Home/DeleteImage";
    $.post(url, { Name: item }, function (data){
        window.location.href = "/Home/Upload";
    });
}

</script> 

Now I want to write a similiar method so you can download each blob from the View. I tried to write the methode using exactly the same code from the delete but instead of

blob.delete();

now

blob.DownloadToFile(File);

This didn't work though. Is there a possibility to change the delete method so it downloads the chosen blob instead of deleting it?


Added Info

Here is the code of DownloadToFile method:

[HttpPost]
    public string DownloadImage(string Name)
    {
        Uri uri = new Uri(Name);
        string filename = System.IO.Path.GetFileName(uri.LocalPath);

        CloudBlobContainer blobContainer = 
_blobStorageService.GetCloudBlobContainer();
        CloudBlockBlob blob = blobContainer.GetBlockBlobReference(filename);

        blob.DownloadToFile(filename, System.IO.FileMode.Create);


        return "File Downloaded";
    }

The name is just the whole filename that is uploaded. Filename is the data path.

The Exception I get is:

UnauthorizedAccessException: The access to the path "C:\Program Files\IIS Express\Eva Passwort.docx" is denied.]

I think that the problem is that my application doesn't have a path to save the file. Is there a possibility to get a dialog where I can chose the path to save?

3 Answers
using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.File;
using OC3.Core.Model.Server;

namespace OC3.API.Controllers
{
    [Route("v1/desktop/[controller]")]
    [ApiController]
    [EnableCors("AllowOrigin")]
    public class DownloadController : Controller
    {
        private readonly IConfiguration _configuration;

        public DownloadController(IConfiguration configuration)
        {
            _configuration = configuration;
        }

        // code added by Ameer for downloading the attachment from shipments
        [HttpGet("Attachment")]
        public async Task<ActionResult> ActionResultAsync(string filepath)
        {
            ResponseMessage responseMessage = new ResponseMessage();

            responseMessage.resultType = "Download";

            try
            {
                if (!string.IsNullOrEmpty(filepath))
                {
                    responseMessage.totalCount = 1;

                    
                    string shareName = string.Empty;        

                    filepath = filepath.Replace("\\", "/");
                    string fileName = filepath.Split("//").Last();
                    if (filepath.Contains("//"))
                    {
                        //Gets the Folder path of the file.
                        shareName = filepath.Substring(0, filepath.LastIndexOf("//")).Replace("//", "/"); 
                    }
                    else
                    {
                        responseMessage.result = "File Path is null/incorrect";
                        return Ok(responseMessage);
                    }

                    string storageAccount_connectionString = _configuration["Download:StorageConnectionString"].ToString();
                    // get file share root reference
                    CloudFileClient client = CloudStorageAccount.Parse(storageAccount_connectionString).CreateCloudFileClient();
                    CloudFileShare share = client.GetShareReference(shareName);

                    // pass the file name here with extension
                    CloudFile cloudFile = share.GetRootDirectoryReference().GetFileReference(fileName);


                    var memoryStream = new MemoryStream();
                    await cloudFile.DownloadToStreamAsync(memoryStream);
                    responseMessage.result = "Success";

                    var contentType = "application/octet-stream";

                    using (var stream = new MemoryStream())
                    {
                        return File(memoryStream.GetBuffer(), contentType, fileName);
                    }
                }
                else
                {
                    responseMessage.result = "File Path is null/incorrect";
                }
            }
            catch (HttpRequestException ex)
            {
                if (ex.Message.Contains(StatusCodes.Status400BadRequest.ToString(CultureInfo.CurrentCulture)))
                {
                    responseMessage.result = ex.Message;
                    return StatusCode(StatusCodes.Status400BadRequest);
                }
            }
            catch (Exception ex)
            {
                // if file folder path or file is not available the exception will be caught here
                responseMessage.result = ex.Message;
                return Ok(responseMessage);
            }

            return Ok(responseMessage);
        }
    }
}
Related