StreamWriter writing to MemoryStream

ediblecode picture ediblecode · Jun 22, 2012 · Viewed 61.9k times · Source

I was under the impression that when you called Flush() in a StreamWriter object it writes to the underlying stream, but apparently this isn't the case with my code.

Instead of writing to my file it will just write nothing. Any ideas where I'm going wrong?

    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");
    }

Answer

David Thielen picture David Thielen · Jun 22, 2012

I believe you need to set Stream.Position = 0. When you write, it advances the position to the end of the stream. When you pass it to File() it starts from the position it is at - the end.

I think the following will work (did not try to compile this):

stream.Position = 0;
return File(stream, "text/plain", "CompetitionEntries.csv");

And this way you are not creating any new objects or copying the underlying array.