0

I need pipeline the PDF or excel file from azure blob storage to front end using an API. i am using download to byte array of blob storage and then convert that to memory stream to send it back to a users.

this is my controller

[AllowAnonymous]
[HttpGet]
[Route("GetFiles")]
public HttpResponseMessage GetFiles()
{
        const string StorageAccountName = "nameofAccount";
        const string StorageAccountKey = "TheKey";
        try
        {
          var storageAccount = new CloudStorageAccount(new StorageCredentials(StorageAccountName, StorageAccountKey), true);// login to azure and storage Account
          
          var bloblClinet = storageAccount.CreateCloudBlobClient();// get blob client refernce

          var container = bloblClinet.GetContainerReference("crmtestblob");// get container refernce 

          var blob = container.GetBlockBlobReference("test.xlsx");
          long fileByteLength = blob.Properties.Length;// this return -1 
          byte[] fileContent = new byte[100000];

          var MyArray = blob.DownloadToByteArray(fileContent, 0);
            
          HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);


          var stream = new MemoryStream(MyArray);//application/octet-stream
            result.Content = new StreamContent(stream);//application/vnd.ms-excel
          result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
          result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
          {
              FileName = "test.xlsx"
          };
          return result;

        }
        catch (Exception ex)
        {
           

            
            return new HttpResponseMessage(HttpStatusCode.InternalServerError);
        }

    }

i get response 200 but no file is sent, or the file is corrupted any help would be great

Community
  • 1
  • 1
Reza Del
  • 763
  • 10
  • 30

2 Answers2

1

You were incorrectly using the function DownloadToByteArray to cause your issue.

According to the offical API reference CloudBlob.DownloadToByteArray(Byte\[\], Int32, AccessCondition, BlobRequestOptions, OperationContext) Method, the return result of the function is The total number of bytes read into the buffer, not the blob content.

There are two SO threads as below which I think their answers are helpful enough for you to fix it.

  1. Downloading a file from Azure Storage to client using Angular2 with .NET Web Api 2

    To use CloudBlob.OpenReadAsync Method to open a readable stream as the response stream content.

    var stream = await blob.OpenReadAsync();
    result.Content = new StreamContent(stream);
    
  2. HttpResponseMessage Redirect to Private Azure Blob Storage

    To redirect the request to blob url with sas token.

    var sasToken = blob.GetSharedAccessSignature(new SharedAccessBlobPolicy()
    {
        Permissions = SharedAccessBlobPermissions.Read,
        SharedAccessExpiryTime = DateTime.UtcNow.AddHours(1)//Assuming you want the link to expire after 1 hour
    });
    var blobUrl = string.Format("{0}{1}", blob.Uri.AbsoluteUri, sasToken);
    var response = Request.CreateResponse(HttpStatusCode.Moved);
    response.Headers.Location = new Uri(bloburl);
    
Peter Pan
  • 23,476
  • 4
  • 25
  • 43
1

Simpler with .Net Core 6 WebAPI

[HttpGet]
    public async Task<IActionResult> Get()
    {

        string connectionString = "DefaultEndpointsProtocol=https;AccountName=";
        string blobContainerName = "container1";
        string blobName = "blob1.csv";
        var blobClient = new BlobClient(connectionString, blobContainerName, blobName);


        var stream = await blobClient.OpenReadAsync();
        return File(stream, "application/octet-stream", "test.csv");
    }
beewest
  • 4,486
  • 7
  • 36
  • 63