New to csvhelper, trying to make sure that I clean up\close all connections once user downloads file, not sure if I've done this right, could anyone advise what I need to do?
public ActionResult ExportClients()
{
var token = new Token(this.User.Identity.Name);
var clients =_clientService.Get(toekn.Id);
var memoryStream = new MemoryStream();
var streamWriter = new StreamWriter(memoryStream);
var csvWriter = new CsvWriter(streamWriter);
csvWriter.WriteRecords(clients);
streamWriter.Flush();
memoryStream.Position = 0;
return File(memoryStream, "text/csv","clients.csv");
}
MemoryStream
, StreamWriter
and CsvWriter
all implement IDisposable
. So, let's take them one at a time:
MemoryStream
FileStreamResult
will dispose of the provided stream for you, which is the result of calling File
at the end of the controller.
StreamWriter
Ordinarily, you'd need to dispose of this yourself, with e.g. a using
statement. In your example, disposing of CsvWriter
will actually do this for you. However, there's a catch. By default:
The StreamWriter object calls Dispose() on the provided Stream object when StreamWriter.Dispose is called.
There's a constructor overload that allows for the underlying Stream
to be left open. You'll need to use this; otherwise, the MemoryStream
will get disposed before the FileStreamResult
gets hold of it and you'll get the dreaded "object already disposed" exception.
CsvWriter
This is the simplest case - You can just dispose of it yourself, using e.g. a using
statement.
Here's the revelant code:
var memoryStream = new MemoryStream();
var streamWriter = new StreamWriter(memoryStream, Encoding.UTF8, 1024, true);
using (var csvWriter = new CsvWriter(streamWriter))
{
csvWriter.WriteRecords(clients);
// No need to flush as the StreamWriter's Dispose takes care of that.
}
memoryStream.Position = 0;
return File(memoryStream, "text/csv","clients.csv");
Unfortunately, there's no constructor for StreamWriter
that allows you to provide just the Stream
and the leaveOpen
flag, so you have to use the one I've used above. The 1024
is the default value, but the Encoding.UTF8
is slightly different. It should suffice, but perhaps someone else will come along and point out how that can be better handled.