簡體   English   中英

在ASP.NET MVC中將文件作為zip文件下載損壞的zip文件下載

[英]Downloading files as a zip result in corrupted zips in ASP.NET MVC

我有一個托管大型XML文件存檔的服務器,並且API在zip中檢索所請求的文件。 如果我選擇大約11個或更少的文件,zip返回就好了。 如果我檢索更多,我在嘗試打開zip時收到以下錯誤:

“Windows無法打開文件夾。壓縮(壓縮)文件夾無效。”

以下是創建zip的數據類和方法:

//Archive file containing filename and content as memory stream
public class ArchiveFile {
    public string FileName;
    public System.IO.MemoryStream FileContent;
}

//Method to retrieve archive files and zip them
public static System.IO.MemoryStream GetFilesAsZip (string[] arrFileNames) {
    MemoryStream zipStream  = null;
    using (zipStream = new MemoryStream()) {
        // Retrieve files using above method
        ArchiveFile[] retrievedFiles = GetFilesFromArchive(arrFileNames);
        // Initialize new ZipArchive on the return object's MemoryStream property
        using (ZipArchive archive = new ZipArchive(zipStream, ZipArchiveMode.Update, leaveOpen: true)) {
            // Write file entries into archive
            foreach (ArchiveFile dataFile in retrievedFiles) {
                if (dataFile.FileContent != null) {
                    // Create new ZipArchiveEntry with content
                    ZipArchiveEntry zipEntry = archive.CreateEntry(dataFile.FileName);
                    dataFile.FileContent.WriteTo(zipEntry.Open());
                }//end if
            } // end foreach
        } //end using
    } //end using
    return zipStream;
}//end method

//API to return content to user as an MVC File Content Result
[HttpGet]
public ActionResult DownloadFiles (string [] fileNames) {
    FileContentResult data = new FileContentResult(GetFiles(fileNames).GetBuffer(), “application/zip”) { FileDownloadName = “files.zip” };
    return data;
} //end method

在寫入內存流時,損壞可能與空間分配有關。 我注意到我所有的“成功”拉鏈(11個或更少的文件)大小為259 KB,但所有“不成功”的拉鏈(超過11個文件)大小為517 KB,一些較大的嘗試拉鏈大小為1034 KB。 這讓我感到非常巧合,因為它們都是258.5 KB的倍數,特別是因為11個文件的拉鏈產生了259 KB的拉鏈,但是12個文件的拉鏈產生了517 KB的拉鏈。

對它可能是什么的任何見解?

ASP.Net Core API Controller返回損壞的excel文件

在你的控制器中返回

return new FileResult("demo.zip", Path.Combine(sWebRootFolder, sFileName), "application/zip");

添加此代碼

public class FileResult : ActionResult
    {
        public FileResult(string fileDownloadName, string filePath, string contentType)
        {
            FileDownloadName = fileDownloadName;
            FilePath = filePath;
            ContentType = contentType;
        }

        public string ContentType { get; private set; }
        public string FileDownloadName { get; private set; }
        public string FilePath { get; private set; }

        public async override Task ExecuteResultAsync(ActionContext context)
        {
            var response = context.HttpContext.Response;
            response.ContentType = ContentType;
            context.HttpContext.Response.Headers.Add("Content-Disposition", new[] { "attachment; filename=" + FileDownloadName });
            using (var fileStream = new FileStream(FilePath, FileMode.Open))
            {
                await fileStream.CopyToAsync(context.HttpContext.Response.Body);
            }
        }
    }

你的代碼被重構了

public byte[] GetFilesAsZip (string[] arrFileNames) {
    byte[] buffer = null;
    using (MemoryStream zipStream = new MemoryStream()) {
        // Retrieve files using above method
        ArchiveFile[] retrievedFiles = GetFilesFromArchive(arrFileNames);
        // Initialize new ZipArchive on the return object's MemoryStream property
        using (ZipArchive archive = new ZipArchive(zipStream, ZipArchiveMode.Update, leaveOpen: true)) {
            // Write file entries into archive
            foreach (ArchiveFile dataFile in retrievedFiles) {
                if (dataFile.FileContent != null) {
                    // Create new ZipArchiveEntry with content
                    ZipArchiveEntry zipEntry = archive.CreateEntry(dataFile.FileName);
                    dataFile.FileContent.WriteTo(zipEntry.Open());
                }//end if
            } // end foreach
        } //end using
        buffer = zipStream.ToArray();
    } //end using
    return buffer;
}//end method

你應該能夠改變它

FileContentResult data = new FileContentResult(GetFiles(fileNames), “application/zip”) { FileDownloadName = “files.zip” };

我在過去做過return File(fileLocation, "application/zip", fileName);已經成功了return File(fileLocation, "application/zip", fileName); 其中fileLocation是文件夾的路徑,fileName是實際文件夾的名稱。 您可以在ActionResult執行此操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM