Why does EPPlus throw System.ObjectDisposedException: Cannot access a closed Stream. after writing to a MemoryStream and seeking to position zero in an ASP.NET MVC application?
public FileStreamResult ExportToExcel()
{
using (var memoryStream = new MemoryStream())
using (var excel = new ExcelPackage())
{
var worksheet = excel.Workbook.Worksheets.Add("Products");
worksheet.Cells["A1"].LoadFromCollection(Collection: myCollection, PrintHeaders: true);
excel.SaveAs(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin); // also tried memoryStream.Position = 0;
return new FileStreamResult(memoryStream, contentType)
{
FileDownloadName = "test.xlsx",
};
}
}
If I move the var memoryStream = ... out of the using statement, it works, but it feels like this could leak a lot of memory for large results until the next garbage collection, if it is not disposed of explicitly. Maybe the ExcelPackage disposes the MemoryStream as well?
[ObjectDisposedException: Cannot access a closed Stream.]
System.IO.__Error.StreamIsClosed() +57
System.IO.MemoryStream.Read(Byte[] buffer, Int32 offset, Int32 count) +10653946
System.Web.Mvc.FileStreamResult.WriteFile(HttpResponseBase response) +80
System.Web.Mvc.FileResult.ExecuteResult(ControllerContext context) +168
System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +13
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +56
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +420
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +420
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +52
System.Web.Mvc.Async.<>c__DisplayClass28.<BeginInvokeAction>b__19() +173
System.Web.Mvc.Async.<>c__DisplayClass1e.<BeginInvokeAction>b__1b(IAsyncResult asyncResult) +100
System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27
System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +13
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +36
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +54
System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +39
System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller) +12
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +28
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +54
System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +29
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__4(IAsyncResult asyncResult, ProcessRequestState innerState) +21
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +36
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +54
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +31
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9629296
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
I think it is because you have your MemoryStream is a using.
This causes (at the end of processing) the stream to be closed and disposed.
Let the FileStreamResult handle closing this, and remove the using.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With