2012-09-13 56 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中它會被延遲。重新編輯添加正確的理由(並添加評論爲什麼你的版本將工作)。 –