Nie wyrzucać MemoryStream
The FileStreamResult
zajmie po jego zakończeniu pisania go do odpowiedzi:
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");
}
}
Przy okazji polecam piszesz wynik niestandardowych działań obsłużyć to zamiast pisanie kodu instalacyjnego wewnątrz akcji kontrolera. Nie tylko, że otrzymasz wynik działania wielokrotnego użytku, ale pamiętaj, że twój kod jest niezwykle nieefektywny => wykonujesz operację ZIP w pamięci i tym samym ładujesz całą zawartość katalogu ~/images + plik zip w pamięci. Jeśli masz dużo użytkowników i dużo plików w tym katalogu, bardzo szybko zabraknie Ci pamięci.
O wiele bardziej efektywnym rozwiązaniem jest napisać bezpośrednio do strumienia odpowiedzi:
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());
}
}
}
, a następnie:
public ActionResult DownloadImagefilesAsZip()
{
return new ZipResult(Server.MapPath("~/Images"), "images.zip");
}
Perfect! Bardzo dziękuję :) –
Musiałem dodać 'memoryStream.Seek (0, SeekOrigin.Begin);' before 'return File (...);', aby to działało. – pqvst