我的印象是,当你在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");
}
答案 0 :(得分:25)
我相信你需要设置Stream.Position = 0
。写入时,它会将位置前进到流的末尾。当你把它传递给File()
时,它从它所处的位置开始 - 结束。
我认为以下内容可行(不尝试编译):
stream.Position = 0;
return File(stream, "text/plain", "CompetitionEntries.csv");
这样您就不会创建任何新对象或复制基础数组。
答案 1 :(得分:8)
您的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包装成使用,您将进入返回已处理的流。
答案 2 :(得分:2)
在玩这个游戏时,我得到了以下原型:
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 = "jsmith@example.com", 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;
}
}