将文件作为压缩文件下载到ASP.NET MVC中的损坏的zip文件中
我有一台托管大型XML文件存档的服务器,并且API在压缩文件中检索请求的文件。如果我选择大约11个或更少的文件,则zip返回正常。如果我检索到更多,我收到试图打开压缩时出现以下错误:“Windows无法打开该文件夹压缩(zipped)文件夹是无效 ”将文件作为压缩文件下载到ASP.NET MVC中的损坏的zip文件中
下面是数据类和方法来创建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个文件的zip文件导致259 KB的zip文件,而12个文件的zip文件导致517 KB zip文件。
任何洞察它可能是什么?
我已经在过去做过成功return File(fileLocation, "application/zip", fileName);
其中fileLocation是文件夹的路径,fileName是实际文件夹的名称。你可以在你的ActionResult
中这样做。在您的控制器
是的,我把另一个问题的完整例子放在一起 –
恐怕这不适合我。拉链不会存储在磁盘上,因为它们是从请求的任何文件组合动态生成的。 – crodriguez
ASP.Net Core API Controller returns corrupted excel file
回报这个
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
你应该能够CH ange这到
FileContentResult data = new FileContentResult(GetFiles(fileNames), “application/zip”) { FileDownloadName = “files.zip” };
你能不能共享XML文件? – Isma
不幸的是,我不能,他们包含私人信息。 – crodriguez
您没有正确使用MemoryStream。而不是在使用之外新建MemoryStream,新建一个字节数组并返回。它的zipStream.ToArray()