'Download blob using Azure Blob storage client library v12 for .NET
I am using Azure.Storage.Blobs version=12.4.1. I have a REST endpoint that I want to use to download blobs from a storage account.
I need to stream the result to a HttpResponseMessage and I do not want to use a MemoryStream. I want to stream the result directly to the calling client. Is there a way to achieve this. How to get the downloaded blob in the HttpResponseMessage content? I do not want to use MemoryStream, since there will be a lot of download requests.
The BlobClient class has a method DownloadToAsync but it requires a Stream as a parameter.
var result = new HttpResponseMessage(HttpStatusCode.OK);
var blobClient = container.GetBlobClient(blobPath);
if (await blobClient.ExistsAsync())
{
var blobProperties = await blobClient.GetPropertiesAsync();
var fileFromStorage = new BlobResponse()
{
ContentType = blobProperties.Value.ContentType,
ContentMd5 = blobProperties.Value.ContentHash.ToString(),
Status = Status.Ok,
StatusText = "File retrieved from blob"
};
await blobClient.DownloadToAsync(/*what to put here*/);
return fileFromStorage;
}
Solution 1:[1]
You could simply create a new memory stream and download the blob's content to that stream.
Something like:
var connectionString = "UseDevelopmentStorage=true";
var blobClient = new BlockBlobClient(connectionString, "test", "test.txt");
var ms = new MemoryStream();
await blobClient.DownloadToAsync(ms);
ms
will have the blob's contents. Don't forget to reset memory stream's position to 0
before using it.
Solution 2:[2]
You need to use
BlobDownloadInfo download = await blobClient.DownloadAsync();
download.Content
is blob Stream. You can use it to copy directly to other stream.
using (var fileStream = File.OpenWrite(@"C:\data\blob.bin"))
{
await download.CopyToAsync(fileStream);
}
Solution 3:[3]
To download a blob using Azure.Storage.Blobs v12.11.0, we can use OpenReadAsync
or OpenRead
string connectionString = Environment.GetEnvironmentVariable("AZURE_STORAGE_CONNECTION_STRING")!;
var serviceClient = new BlobServiceClient(connectionString);
var container = serviceClient.GetBlobContainerClient("myblobcontainername");
string blobName; // the name of the blob
var client = container.GetBlobClient(HttpUtility.UrlDecode(blobName));
var properties = (await client.GetPropertiesAsync()).Value;
Response.Headers.Add("Content-Disposition", $"attachment; filename={Path.GetFileName(client.Name)}");
Response.Headers.Add("Content-Length", $"{properties.ContentLength}");
return File(await client.OpenReadAsync(), properties.ContentType);
Solution 4:[4]
Try to use the code as below to download blob into HttpResponseMessage.
try
{
var storageAccount = CloudStorageAccount.Parse("{connection string}");
var blobClient = storageAccount.CreateCloudBlobClient();
var Blob = await blobClient.GetBlobReferenceFromServerAsync(new Uri("https://{storageaccount}.blob.core.windows.net/{mycontainer}/{blobname.txt}"));
var isExist = await Blob.ExistsAsync();
if (!isExist) {
return Request.CreateErrorResponse(HttpStatusCode.NotFound, "file not found");
}
HttpResponseMessage message = new HttpResponseMessage(HttpStatusCode.OK);
Stream blobStream = await Blob.OpenReadAsync();
message.Content = new StreamContent(blobStream);
message.Content.Headers.ContentLength = Blob.Properties.Length;
message.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(Blob.Properties.ContentType);
message.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
{
FileName = "{blobname.txt}",
Size = Blob.Properties.Length
};
return message;
}
catch (Exception ex)
{
return new HttpResponseMessage
{
StatusCode = HttpStatusCode.InternalServerError,
Content = new StringContent(ex.Message)
};
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Gaurav Mantri |
Solution 2 | Piotr Perak |
Solution 3 | kimbaudi |
Solution 4 | Joey Cai |