无法在MVC操作中返回CSV文件.无法访问封闭的流媒体



在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 [] buffer,int32 offset,int32 count) 10909062 system.web.mvc.filestreamresult.writefile(httpresponsebase响应) 157 system.web.mvc.fileresult.executeresult(contranterContext上下文) 296 system.web.mvc.controllerActionInvoker.invokeactionResult(contranceerContext ControllerContext,ActionResresult ActionResult) 39 system.web.mvc.controllerActionInVoker.invokeactionResultFilterRecursiver(IList 1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +116 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList 1滤波器,Int32 filterIndex,resultexecutingContext Provontext,contranceerContext contrance contranceerContercext,contrance contrance contranceercontext, system.web.mvc.controllerActionInVoker.invokeactionResultFilterRecursiver(ILIST 1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +529 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList 1过滤器,Action Result Action Reserult) 106 system.web.mvc.async。 system.web.mvc.async。 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,对象标签) 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() 139 system.web.mvc.async.asyncresultwrapper.end(iasyncresult asyncresult,对象标签) 59 system.web.mvc.async.asyncresultwrapper.end(iasyncresult asyncresult,对象标签) 40 system.web.mvc.controller.endexecutecore(iasyncresult asyncresult) 44 system.web.mvc.controller.b_ 15(iasyncresult asyncresult,控制器控制器) 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,对象标签) 59 system.web.mvc.async.asyncresultwrapper.end(iasyncresult asyncresult,对象标签) 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() 139 system.web.mvc.async.asyncresultwrapper.end(iasyncresult asyncresult,对象标签) 59 system.web.mvc.async.asyncresultwrapper.end(iasyncresult asyncresult,对象标签) 40 system.web.mvc.mvchandler.endprocessrequest(iasyncresult asyncresult) 40 system.web.mvc.mvchandler.system.web.ihttpasynchandler.endprocessrequest(iasyncresult结果) 38 system.web.callhandlerexecutionstep.system.web.httpapplication.iexecutionstep.execute() 9514928 system.web.httpapplication.executestep(iexecutionStep step,boolean&amp; poutthsedsysly) 155

谢谢,Miguel

您的使用语句正在关闭您要在文件中返回的内存流。

这应该修复它。在块外声明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");
  }
}

另外,您可以使用fileerSponse的字节[]过载。

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");
}

最新更新