Sie das MemoryStream
nicht entsorgen, die FileStreamResult
darauf achten wird, sobald sie es auf die Antwort fertig geschrieben hat:
public ActionResult DownloadImagefilesAsZip()
{
var memoryStream = new MemoryStream();
using (var zip = new ZipFile())
{
zip.AddDirectory(Server.MapPath("~/Images"));
zip.Save(memoryStream);
return File(memoryStream, "application/gzip", "images.zip");
}
}
Durch die Art und Weise würde ich empfehlen Sie eine benutzerdefinierte Aktion Ergebnis zu schreiben, dies zu umgehen, anstatt Klempnercode in Ihre Controller-Aktion schreiben. Nicht nur, dass Sie ein wiederverwendbares Aktionsergebnis erhalten, sondern auch, dass Ihr Code sehr ineffizient ist => Sie führen den ZIP-Vorgang im Speicher aus und laden so den gesamten ~/images Verzeichnisinhalt + die ZIP-Datei im Speicher. Wenn Sie viele Benutzer und viele Dateien in diesem Verzeichnis haben, wird Ihnen sehr schnell der Speicher ausgehen.
Eine viel effizientere Lösung ist direkt in den Antwortstream zu schreiben:
public class ZipResult : ActionResult
{
public string Path { get; private set; }
public string Filename { get; private set; }
public ZipResult(string path, string filename)
{
Path = path;
Filename = filename;
}
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
var response = context.HttpContext.Response;
response.ContentType = "application/gzip";
using (var zip = new ZipFile())
{
zip.AddDirectory(Path);
zip.Save(response.OutputStream);
var cd = new ContentDisposition
{
FileName = Filename,
Inline = false
};
response.Headers.Add("Content-Disposition", cd.ToString());
}
}
}
und dann:
public ActionResult DownloadImagefilesAsZip()
{
return new ZipResult(Server.MapPath("~/Images"), "images.zip");
}
Perfect! Vielen Dank :) –
Ich musste 'memoryStream.Seek (0, SeekOrigin.Begin);' vor 'return File (...);' hinzufügen, damit es funktioniert. – pqvst