StreamWriterオブジェクトでFlush()
を呼び出すと、基になるストリームに書き込むという印象を受けましたが、私のコードではそうではありません。
私のファイルに書き込む代わりに、何も書き込みません。私が間違っているアイデアはありますか?
public FileResult DownloadEntries(int id)
{
Competition competition = dataService.GetCompetition(id);
IQueryable<CompetitionEntry> entries = dataService.GetAllCompetitionEntries().Where(e => e.CompetitionId == competition.CompetitionId);
MemoryStream stream = new MemoryStream();
StreamWriter csvWriter = new StreamWriter(stream, Encoding.UTF8);
csvWriter.WriteLine("First name,Second name,E-mail address,Preferred contact number,UserId\r\n");
foreach (CompetitionEntry entry in entries)
{
csvWriter.WriteLine(String.Format("{0},{1},{2},{3},{4}",
entry.User.FirstName,
entry.User.LastName,
entry.User.Email,
entry.User.PreferredContactNumber,
entry.User.Id));
}
csvWriter.Flush();
return File(stream, "text/plain", "CompetitionEntries.csv");
}
_Stream.Position = 0
_を設定する必要があると思います。書き込むと、ストリームの最後に位置が進みます。 File()
に渡すと、現在の位置から始まり、最後になります。
私は以下がうまくいくと思います(これをコンパイルしようとはしませんでした):
_stream.Position = 0;
return File(stream, "text/plain", "CompetitionEntries.csv");
_
この方法では、新しいオブジェクトを作成したり、基になる配列をコピーしたりすることはありません。
MemoryStreamは最後に配置されます。より良いコードは、 MemoryStream(Byte []、Int32、Int32、Boolean) コンストラクタを使用して、同じバッファに新しいR/Oメモリストリームを作成することです。
トリミングされたバッファーでの最も単純なr/w:
return File(new MemoryStream(stream.ToArray());
内部バッファをコピーしないR/O:
return File(new MemoryStream(stream.GetBuffer(), 0, (int)stream.Length, false);
注:File(Stream)を介して返すストリームを破棄しないように注意してください。それ以外の場合は、ある種の「ObjectDisposedException」が発生します。つまり元のストリームの位置を0に設定し、StreamWriterをラップして使用すると、破棄されたストリームが返されます。
これで遊んで、私は次のプロトタイプを機能させました:
using System.Web.Mvc;
using NUnit.Framework;
namespace StackOverflowSandbox
{
[TestFixture]
public class FileStreamResultTest
{
public FileStreamResult DownloadEntries(int id)
{
// fake data
var entries = new[] {new CompetitionEntry { User = new Competitor { FirstName = "Joe", LastName = "Smith", Email = "[email protected]", Id=id.ToString(), PreferredContactNumber = "555-1212"}}};
using (var stream = new MemoryStream())
{
using (var csvWriter = new StreamWriter(stream, Encoding.UTF8))
{
csvWriter.WriteLine("First name,Second name,E-mail address,Preferred contact number,UserId\r\n");
foreach (CompetitionEntry entry in entries)
{
csvWriter.WriteLine(String.Format("{0},{1},{2},{3},{4}",
entry.User.FirstName,
entry.User.LastName,
entry.User.Email,
entry.User.PreferredContactNumber,
entry.User.Id));
}
csvWriter.Flush();
}
return new FileStreamResult(new MemoryStream(stream.ToArray()), "text/plain");
}
}
[Test]
public void CanRenderTest()
{
var fileStreamResult = DownloadEntries(1);
string results;
using (var stream = new StreamReader(fileStreamResult.FileStream))
{
results = stream.ReadToEnd();
}
Assert.IsNotEmpty(results);
}
}
public class CompetitionEntry
{
public Competitor User { get; set; }
}
public class Competitor
{
public string FirstName;
public string LastName;
public string Email;
public string PreferredContactNumber;
public string Id;
}
}