Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

File Size Goes to Zero when Returning FileStreamResult from MVC Controller

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.

like image 410
MoonKnight Avatar asked Nov 26 '14 14:11

MoonKnight


People also ask

What does ActionResult Return?

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.

What is Index action method in MVC?

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.

What is controller in MVC c#?

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.


1 Answers

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)
like image 61
b2zw2a Avatar answered Sep 30 '22 18:09

b2zw2a