从MVC控制器返回FileStreamResult时,文件大小变为零

10

我正在尝试以CloudBlockBlob的形式从Azure存储中下载文件。我想要允许用户选择下载文件的位置,因此我编写了以下代码来实现这一点

[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);
}
这将从Blob存储下载文件,但是当控制器使用FileStreamResult返回视图时,浏览器会像预期的那样启动保存文件对话框,但文件大小为0字节。 Stream显示了正确的文件大小,但当我执行......
 return File(stream, contentType, displayName);

数据似乎没有传递到保存对话框中。

我该如何使文件正确保存?

感谢您的时间。


3
在返回文件结果之前,你尝试将流索引重置为零了吗? - danludwig
不,我没有。我不知道这会有所不同。为什么这有帮助呢?不管怎样,我现在会尝试一下。感谢你的时间。 - MoonKnight
这很有帮助,因为读取或写入流会移动其位置。例如,将文件写入流会将位置设置在已写入数据的末尾,准备进行更多的写入。然后,当您的File()尝试读取时,它从当前位置开始读取,但由于我们已经到达了末尾,所以什么也没有读取。如果您将其设置为零,则该读取将从零开始,并读取您写入的所有内容。 - Steve Lillis
1个回答

19

DownloadRangeToStreamAsync完成后,你的内存流位置将在最后一个字节上。在返回之前,请将其设置回开头。

stream.Seek(0,0)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接