Non smaltire il MemoryStream
, il FileStreamResult
si prenderà cura una volta che ha finito di scrivere alla risposta:
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");
}
}
proposito vi consiglio di scrivere di conseguenza un'azione personalizzata per gestire questa situazione, invece di scrivere il codice dell'impianto idraulico all'interno dell'azione del controller. Non solo avrai un risultato d'azione riutilizzabile, ma ricordati che il tuo codice è estremamente inefficiente => stai eseguendo l'operazione ZIP all'interno della memoria e quindi carichi l'intero contenuto della directory ~/images + il file zip in memoria. Se ci sono molti utenti e molti file in questa directory, la memoria si esaurirà molto rapidamente.
Un molto più efficiente soluzione è quella di scrivere direttamente al flusso di risposta:
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());
}
}
}
e poi:
public ActionResult DownloadImagefilesAsZip()
{
return new ZipResult(Server.MapPath("~/Images"), "images.zip");
}
fonte
2012-10-16 17:02:29
Perfetto! Grazie mille :) –
Ho dovuto aggiungere 'memoryStream.Seek (0, SeekOrigin.Begin);' prima 'return File (...);' per farlo funzionare. – pqvst