を破棄しないでください。応答への書き込みが完了すると、 が処理しますMemoryStream
。FileStreamResult
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");
}
}
ところで、コントローラー アクション内に配管コードを記述する代わりに、カスタム アクション結果を記述してこれを処理することをお勧めします。再利用可能なアクション結果が得られるだけでなく、コードが非常に非効率的であることに注意してください => メモリ内で ZIP 操作を実行しているため、~/images ディレクトリの内容全体と zip ファイルをメモリにロードしています。このディレクトリ内に多数のユーザーと多数のファイルがある場合、すぐにメモリ不足になります。
はるかに効率的な解決策は、応答ストリームに直接書き込むことです。
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());
}
}
}
その後:
public ActionResult DownloadImagefilesAsZip()
{
return new ZipResult(Server.MapPath("~/Images"), "images.zip");
}