Search code examples
azureasp.net-coreazure-blob-storageazure-storage

Why can't I download an Azure Blob using an asp.net core application published to Azure server


I am trying to download a Blob from an Azure storage account container. When I run the application locally, I get the correct "Download" folder C:\Users\xxxx\Downloads. When I publish the application to Azure and try to download the file, I get an error. I have tried various "Knownfolders", and some return empty strings, others return the folders on the Azure server. I am able to upload files fine, list the files in a container, but am struggling with downloading a file.

string conn = 
configuration.GetValue<string>"AppSettings:AzureContainerConn");
CloudStorageAccount storageAcct = CloudStorageAccount.Parse(conn);
CloudBlobClient blobClient = storageAcct.CreateCloudBlobClient();
CloudBlobContainer container = 
blobClient.GetContainerReference(containerName);

 Uri uriObj = new Uri(uri);

string filename = Path.GetFileName(uriObj.LocalPath);

// get block blob reference  
CloudBlockBlob blockBlob = container.GetBlockBlobReference(filename);

Stream blobStream = await blockBlob.OpenReadAsync();

string _filepath = _knownfolder.Path + "\\projectfiles\\";
Directory.CreateDirectory(_filepath);

_filepath = _filepath + filename;
Stream _file = new MemoryStream();
try
{
 _file = File.Open(_filepath, FileMode.Create, FileAccess.Write);

 await blobStream.CopyToAsync(_file);
 }
finally
{
  _file.Dispose();
}

The expected end result is the file ends up in the folder within the users "Downloads" folder.


Solution

  • Since you're talking about publishing to Azure, the code is probably from a web application, right? And the code for the web application runs on the server. Which means the code is trying to download the blob to the server running the web application.

    To present a downloadlink to the user to enable them to download the file, use the FileStreamResult which

    Represents an ActionResult that when executed will write a file from a stream to the response.

    A (pseudo code) example:

    [HttpGet]
    public FileStreamResult GetFile()
    {
      var stream = new MemoryStream();
      CloudBlockBlob blockBlob = container.GetBlockBlobReference(filename);
      blockBlob.DownloadToStream(stream);
      blockBlob.Seek(0, SeekOrigin.Begin);
      return new FileStreamResult(stream, new MediaTypeHeaderValue("text/plain"))
      {
        FileDownloadName = "someFile.txt"
      };
    }