无法在MVC操作中返回CSV文件。 不能访问封闭的Streamable

在ASP.NET MVC操作上,我试图用用户信息返回一个CSV文件:

  IList<UserModel> users = _repository.GetUsers();

  MemoryStream stream = new MemoryStream;
    using (StreamWriter writer = new StreamWriter(stream)) {
      using (CsvWriter csv = new CsvWriter(writer)) {
        csv.Configuration.With(x => {
          x.AutoMap<UserModel>();
          x.RegisterClassMap<UserModelCsvMapper>();
        });            
        csv.WriteRecords(reply.Users);
        writer.Flush();
        return File(stream, "text/csv", "Users.csv");
      }
    }

我有以下映射器:

public class UserModelCsvMapper : CsvClassMap<UserModel> {
  public override void CreateMap() {
    Map(x => x.Name).Name("Name");
    Map(x => x.Email).Name("Email");
    Map(x => x.Linked).Name("Linked");
  } // CreateMap
} // UserModelCsvMapper

我的CSV作家似乎是空的,当我返回流时,我得到的错误:

((System.IO.Stream)(stream)).WriteTimeout' threw an exception of type 'System.InvalidOperationException'

我得到错误页面:

Cannot access a closed Stream.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.ObjectDisposedException: Cannot access a closed Stream.

更新:添加堆栈跟踪

无法访问关闭的流。 说明:执行当前Web请求期间发生未处理的异常。 请查看堆栈跟踪以获取有关该错误的更多信息以及源代码的位置。

异常详细信息:System.ObjectDisposedException:无法访问关闭的流。

源错误:

在执行当前Web请求期间生成未处理的异常。 关于异常的来源和位置的信息可以使用下面的异常堆栈跟踪来标识。

堆栈跟踪:

[ObjectDisposedException:无法访问关闭的流。] System.IO._Error.StreamIsClosed()+57 System.IO.MemoryStream.Read(Byte []缓冲区,Int32偏移量,Int32计数)+10909062 System.Web.Mvc.FileStreamResult。 WriteFile(HttpResponseBase响应)+157 System.Web.Mvc.FileResult.ExecuteResult(ControllerContext上下文)+296 System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext,ActionResult actionResult)+39 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive( IList 1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +116 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList 1 filters,Int32 filterIndex,ResultExecutingContext preContext,ControllerContext controllerContext,ActionResult actionResult)+529 System.Web。 Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList 1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +529 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList 1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +529 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList 1 filters,ActionResult actionResult)+106 System.Web.Mvc.Async。<> c_DisplayClass2b.b_1c()+321 System.Web.Mvc.Async。<> c_DisplayClass21.b_1e(IAsyncResult asyncResult)+185 System.Web.Mvc.Async.WrappedAsyncResult 1.CallEndDelegate(IAsyncResult asyncResult) +42 System.Web.Mvc.Async.WrappedAsyncResultBase 1.End( )+133 System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult,Object tag)+56 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult)+40 System.Web.Mvc.Controller.b_1d( IAsyncResult asyncResult,ExecuteCoreState innerState)+34 System.Web.Mvc.Async.WrappedAsyncVoid 1.CallEndDelegate(IAsyncResult asyncResult) +70 System.Web.Mvc.Async.WrappedAsyncResultBase 1.End() 1.CallEndDelegate(IAsyncResult asyncResult) +70 System.Web.Mvc.Async.WrappedAsyncResultBase 139 System.Web.Mvc.Async。 AsyncResultWrapper.End(IAsyncResult asyncResult, Object标签)+59 System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult,Object tag)+40 System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult)+44 System.Web.Mvc.Controller.b_15( IAsyncResult asyncResult,Controller controller)+39 System.Web.Mvc.Async.WrappedAsyncVoid 1.CallEndDelegate(IAsyncResult asyncResult) +62 System.Web.Mvc.Async.WrappedAsyncResultBase 1.End()+139 System.Web.Mvc.Async。 AsyncResultWrapper.End(IAsyncResult asyncResult,Object tag)+59 System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult,Object tag)+40 System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult)+39 System.Web .Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult)+39 System.Web.Mvc.MvcHandler.b_5(IAsyncResult asyncResult,ProcessRequestState innerState)+39 System.Web.Mvc.Async.WrappedAsyncVoid 1.CallEndDelegate(IAsyncResult asyncResult) +70 System.Web.Mvc.Async.WrappedAsyncResultBase 1.End() 1.CallEndDelegate(IAsyncResult asyncResult) +70 System.Web.Mvc.Async.WrappedAsyncResultBase 139 System.Web.Mvc.Async。 AsyncResultWrapper.End(IAsyncResult asyncResult,Object tag)+59 System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult,Object tag)+40 System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)+40 System.Web .Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)+38 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()+9514928 System.Web.HttpApplication.ExecuteStep(IExecutionStep step,Boolean&completedSynchronously )+155

谢谢你,米格尔


您的使用语句将关闭您在FileResult中返回的内存流。

这应该解决它。 在块外声明MemoryStream 。 一旦流被完全写入Response流,它将被框架关闭(尽管关闭MemoryStream目前不是必需的,当它们被垃圾收集时它们会被正确清理。

IList<UserModel> users = _repository.GetUsers();

var stream = new MemoryStream();
using (StreamWriter writer = new StreamWriter(stream)) {
  using (CsvWriter csv = new CsvWriter(writer)) {
      csv.Configuration.With(x => {
      x.AutoMap<UserModel>();
      x.RegisterClassMap<UserModelCsvMapper>();  
    });            
    csv.WriteRecords(reply.Users)
    writer.Flush();
    return File(stream, "text/csv", "Users.csv");
  }
}

或者,您可以使用FileResponse的Byte []重载。

using (var stream = new MemoryStream())
using (StreamWriter writer = new StreamWriter(stream))
using (CsvWriter csv = new CsvWriter(writer) {
  csv.Configuration.With(x => {
    x.AutoMap<UserModel>();
    x.RegisterClassMap<UserModelCsvMapper>();  
  })        

  //use the users that you just retrieved from the repository
  csv.WriteRecords(users)
  writer.Flush();

  return File(stream.ToArray(), "text/csv", "Users.csv");
}
链接地址: http://www.djcxy.com/p/85125.html

上一篇: Not able to return CSV file in MVC action. Not Cannot access a closed Streamable

下一篇: Strange asp.net mvc error