无法访问 ASP.NET MVC 应用程序中的 Response.OutputStream,因为它已关闭

Cannot access Response.OutputStream in an ASP.NET MVC application because it's closed

我正在尝试从另一个域在我的 Web 应用程序中传输文件,我会将这些文件压缩以供下载。为此,我使用 Ionic Zip。但是我的代码中标记的行出现了这个错误:

System.ObjectDisposedException: No access to a closed Stream.

这是我的代码。我在 ASP.NET MVC 应用程序中使用 C#。

using Ionic.Zip;
using System.IO;
using System.Net;

[HttpPost]
public async Task<ActionResult> Downloads(string lang, string product, IEnumerable<string> file, string action)
{
    string zipname = "manuals.zip";

    using (ZipFile zip = new ZipFile())
    {
        foreach (string f in file.Distinct())
        {
            using (WebClient client = new WebClient())
            {
                using (MemoryStream output = new MemoryStream())
                {
                    byte[] b = client.DownloadData(f);
                    await output.WriteAsync(b, 0, b.Length);
                    await output.FlushAsync();
                    output.Position = 0;
                    zip.AddEntry(f.Split('/').Last(), output);
                    output.Close();
                }
            }
        }

        Response.Clear();
        Response.ContentType = "application/zip, application/octet-stream";
        Response.AddHeader("content-disposition", $"attachment; filename={product.Replace('/', '-')}-{zipname}");
        zip.Save(Response.OutputStream); // ← error on this line
        Response.End();
    }
}

这段代码有什么问题?

通过@rene 的评论,我找到了一个有效的答案。他说:

Could you test what happens if you don't dispose the MemoryStream and don't call close on it. It might be that reading the actual memory stream is deferred until Save is called. In your code all those streams are then already closed, disposed and maybe even GC'd.

在这里查看我的代码。

using Ionic.Zip;
using System.IO;
using System.Net;

[HttpPost]
public ActionResult Downloads(string lang, string product, IEnumerable<string> file, string action)
{
    string zipname = "manuals.zip";
    List<MemoryStream> streams = new List<MemoryStream>();

    using (ZipFile zip = new ZipFile())
    {
        foreach (string f in file.Distinct())
        {
            using (WebClient client = new WebClient())
            {
                MemoryStream output = new MemoryStream();
                byte[] b = client.DownloadData(f);

                output.Write(b, 0, b.Length);
                output.Flush();
                output.Position = 0;
                zip.AddEntry(f.Split('/').Last(), output);

                // output.Close(); // ← removed this line
                streams.Add(output);
            }
        }

        Response.Clear();
        Response.ContentType = "application/zip, application/octet-stream";
        Response.AddHeader("content-disposition", $"attachment; filename={product.Replace('/', '-')}-{zipname}");
        zip.Save(Response.OutputStream);

        foreach (MemoryStream stream in streams)
        {
            stream.Close();
            stream.Dispose();
        }

        Response.End();
    }
}

为了确保所有流都关闭,我将所有打开的 MemoryStream 添加到列表中,在 Response.End(); 之前,我关闭并处理它们。