c# - 使用 C# 创建的 ZipArchive 不包含任何条目

标签 c# asp.net asp.net-mvc

我正在尝试在 ASP.NET MVC 中创建一个 zip 文件,其中包含一个 PDF 文件。但是,使用下面的代码,会创建一个空的 zip 文件。有人可以告诉我做错了什么吗?

public FileResult DownloadZipfile(string html)
{
    MemoryStream memoryStream = new MemoryStream();
    ZipArchive archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true);

    byte[] rawDownload = PDFConverterUtils.PdfSharpConvert(html);

    ZipArchiveEntry entry = archive.CreateEntry("MyPDF.pdf");

    using (Stream entryStream = entry.Open())
    using (StreamWriter streamWriter = new StreamWriter(entryStream))
    {
        streamWriter.BaseStream.Write(rawDownload, 0, rawDownload.Length);
    }

    return new FileStreamResult(memoryStream, System.Net.Mime.MediaTypeNames.Application.Zip) { FileDownloadName = "test.zip" };

}

最佳答案

ZipArchiveMemoryStream 一起使用时,我建议在写入后重置流的位置,以便流的内容可以被响应。

public FileResult DownloadZipfile(string html) {
    
    byte[] rawDownload = PDFConverterUtils.PdfSharpConvert(html);
    
    MemoryStream memoryStream = new MemoryStream();
    using(ZipArchive archive = new ZipArchive(
        stream: memoryStream, 
        mode: ZipArchiveMode.Create, 
        leaveOpen: true //To leave the memory stream open after disposal
    )){
        ZipArchiveEntry entry = archive.CreateEntry("MyPDF.pdf");
        using (Stream entryStream = entry.Open()) {
            entryStream.Write(rawDownload, 0, rawDownload.Length);
        }
    }
    memoryStream.Position = 0;//reset memory stream position for read
    return new FileStreamResult(memoryStream, System.Net.Mime.MediaTypeNames.Application.Zip) {
        FileDownloadName = "test.zip" 
    };
}

正如另一个答案中所建议的,您应该处理存档以强制它将其内容写入其底层内存流,但请注意以下几点

ZipArchive.Dispose()

Unless you construct the object by using the ZipArchive(Stream, ZipArchiveMode, Boolean) constructor overload and set its leaveOpen parameter to true, all underlying streams are closed and no longer available for subsequent write operations.

When you are finished using this instance of ZipArchive, call Dispose() to release all resources used by this instance. You should eliminate further references to this ZipArchive instance so that the garbage collector can reclaim the memory of the instance instead of keeping it alive for finalization.

因为要在写入后使用内存流,所以需要确保它保持打开状态,并且流的位置被重置为开始,以便可以读取流的内容从一开始。

关于c# - 使用 C# 创建的 ZipArchive 不包含任何条目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50340562/

相关文章:

带有 CssClass 的 ASP.net 按钮不起作用

c# - 表单在客户端桌面区域内移动

c# - 您可以更改类型化数据集提供程序吗?

c# - ASP.NET MVC - 将多个变量传递给模型?

c# - Server.MapPath 和空格

javascript - 如何使用 htmlhelpers 或 JavaScript 从 URL 获取路由值?

c# - MVC自定义认证,filterContext为null

c# - 在路由属性中添加默认操作

c# - 是否可以在不购买 Visual Studio 许可证的情况下使用团队资源管理器进行版本控制?

c# - 如何为音频剪辑的长度实例化对象