I am attempting to download a file from Azure Storage in the form of an CloudBlockBlob. I want to allow the user to select where to put the downloaded file, so I have written the following code to do this
[AllowAnonymous]
public async Task<ActionResult> DownloadFile(string displayName)
{
ApplicationUser user = null;
if (ModelState.IsValid)
{
user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
// Retrieve storage account and blob client.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
ConfigurationManager.AppSettings["StorageConnectionString"]);
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference(
VisasysNET.Utilities.Constants.ContainerName);
// If the container does not exist, return error.
if (container.Exists())
{
foreach (IListBlobItem item in container.ListBlobs(null, false))
{
if (item.GetType() == typeof(CloudBlockBlob))
{
CloudBlockBlob blob = (CloudBlockBlob)item;
if (blob.Name.CompareNoCase(displayName))
{
string contentType = String.Format(
"application/{0}",
Path.GetExtension(displayName).TrimStart('.'));
// No need to dispose, FileStreamResult will do this for us.
Stream stream = new MemoryStream();
await blob.DownloadRangeToStreamAsync(stream, null, null);
return File(stream, contentType, displayName);
}
}
}
return RedirectToAction("Index", "Tools");
}
}
return new HttpStatusCodeResult(HttpStatusCode.ServiceUnavailable);
}
This downloads the file from the blob storage fine, but when the controller returns to the view using FileStreamResult
, the browser is launching the save file dialog as expected but the file size is 0 bytes. The Stream
shows that the correct file size, but when I do
return File(stream, contentType, displayName);
the data does not seem to be passed to the save dialog.
How can I get the file to save properly?
Thanks for your time.
An action result is what a controller action returns in response to a browser request. The ASP.NET MVC framework supports several types of action results including: ViewResult - Represents HTML and markup. EmptyResult - Represents no result.
You can see in the above action method example that the Index() method is a public method which is inside the HomeController class. And the return type of the action method is ActionResult. It can return using the “View()” method. So, every public method inside the Controller is an action method in MVC.
A controller is responsible for controlling the way that a user interacts with an MVC application. A controller contains the flow control logic for an ASP.NET MVC application. A controller determines what response to send back to a user when a user makes a browser request.
Your memorystream position after DownloadRangeToStreamAsync
will be on the last byte. Set it back to the begining before you return it.
stream.Seek(0,0)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With