Here is how I implemented downloading of a file in Azure function with .NET 5:
HttpResponseData response = req.CreateResponse(hasRangeHeader ? HttpStatusCode.PartialContent : HttpStatusCode.OK);
response.WriteBytes(memoryStream.ToArray());
response.Headers.Add("Content-Type", properties.Value.ContentType);
response.Headers.Add("Accept-Ranges", $"bytes");
response.Headers.Add("Content-Disposition", $"attachment; filename={blobClient.Name}; filename*=UTF-8'{blobClient.Name}");
return response;
And here is the complete function class:
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace UploadMediaFunction
{
public class GetMediaFileFunction
{
private readonly ILogger _logger;
public GetMediaFileFunction(ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<GetMediaFileFunction>();
}
[Function("GetMediaFile")]
public async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequestData req, string name)
{
if (string.IsNullOrEmpty(name))
throw new ArgumentNullException(nameof(name));
BlobContainerClient container = await GetCloudContainer();
BlobClient blobClient = container.GetBlobClient(name);
BlobDownloadInfo download = await blobClient.DownloadAsync();
var properties = blobClient.GetProperties();
long startPosition = 0;
bool hasRangeHeader = false;
if (req.Headers.TryGetValues("Range", out IEnumerable<string> values) && values.Any())
{
string[] range = values.First().ToString().Split(new char[] { '=', '-' });
startPosition = long.Parse(range[1]);
hasRangeHeader = true;
}
MemoryStream memoryStream = new();
download.Content.CopyTo(memoryStream);
memoryStream.Position = startPosition;
HttpResponseData response = req.CreateResponse(hasRangeHeader ? HttpStatusCode.PartialContent : HttpStatusCode.OK);
response.WriteBytes(memoryStream.ToArray());
response.Headers.Add("Content-Type", properties.Value.ContentType);
response.Headers.Add("Accept-Ranges", $"bytes");
response.Headers.Add("Content-Disposition", $"attachment; filename={blobClient.Name}; filename*=UTF-8'{blobClient.Name}");
return response;
}
public static async Task<BlobContainerClient> GetCloudContainer()
{
var containerName = Environment.GetEnvironmentVariable("BlobStorageContainerName");
containerName = Regex.Replace(containerName, @"[^0-9a-zA-Z]+", "-").Replace("--", "-");
var connectionString = Environment.GetEnvironmentVariable("BlobStorageStorageConnectionString");
BlobServiceClient blobServiceClient = new(connectionString);
var blobContainerClient = blobServiceClient.GetBlobContainerClient(containerName);
if (!blobContainerClient.Exists())
await blobContainerClient.CreateAsync();
return blobContainerClient;
}
}
}