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.

このアクションは機能しません。ダウンロード アクションを作成するにはどうすればよいですか?

4

1 に答える 1

5

「このアクションは機能しません」は問題を説明する間違った方法です...

ただし、この場合は幸運です。最後までシークされたメモリストリームで不完全なデータを送信しようとしているため、2番目の問題のストリームは、ファイルアクションが実際に実行されるまでに破棄されます。

最善の修正は、コードを内部から移動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によって提案されたFlush+Seekは、ストリームをすぐに使用している他の場合にも機能します。

writer.Flush();
memoStream.Flush();
memoStream.Position = 0;    
// do something with MemoryStream right here before either of `using`ends.
于 2012-09-13T06:10:10.863 に答える