2012-09-13 58 views
2
public ActionResult GetFile(string dateStr, string serverName, string foodName) 
{ 
     using (var memoStream = new MemoryStream(1024 * 5)) 
     { 
      using (StreamWriter writer = new StreamWriter(memoStream)) 
      { 
       var dataFilter = new CapacityDataFilter(dateStr, serverName, feedName); 
       dataFilter.FilterDataByServerAndFeed(); 
       writer.WriteLine("Feed, StreamMin, TotalMsgNumber, TotalMsgSize, PeakRateMsgNumber, PeakRateMsgSize"); 

       foreach (var element in dataFilter.DataInTheDay) 
       { 
        writer.WriteLine(string.Format("{0},{1},{2},{3},{4},{5}", 
          element.Feed, element.StreamMin, 
          element.TotalMsgNumber, element.TotalMsgSize, 
          element.PeakRateMsgNumber, element.PeakRateMsgSize)); 
       } 


       return File(memoStream, "text/csv", fileName); 
      } 
     } 
} 

Exception Details: System.ObjectDisposedException: Cannot access a closed Stream.asp.net的MVC生成的数据下载文件

这一行动是不行的,如何让下载操作?

回答

5

“这个动作无法正常工作”是错误的方式来解释问题...

但在这种情况下,你是幸运的:您要发送的seeked到年底内存流不完整的数据,并作为第二个问题流将在文件操作实际执行时处理。

最好的解决方法是把代码outisde内using和原有数据流的缓冲区返回新的MemoryStream:

using (var memoStream = new MemoryStream(1024 * 5)) 
{ 
    using (StreamWriter writer = new StreamWriter(memoStream)) 
    { 
... 
    } 
    return File(
     new MemoryStream(memoStream.GetBuffer(), memoStream.length), 
     "text/csv", fileName); 
} 

冲洗+搜索时使用的是所建议的armen.shimoon会在其他情况下,工作太立即流:

writer.Flush(); 
memoStream.Flush(); 
memoStream.Position = 0;  
// do something with MemoryStream right here before either of `using`ends. 
+1

啊,说得通。实际结果仅在内存流的使用块退出后执行。 –

+0

@ armen.shimoon,感谢您的评论。我完全忘记了一个事实,即在我进行第一次编辑时,在MVC中它会被延迟。重新编辑添加正确的理由(并添加评论为什么你的版本将工作)。 –