6

In a business app I am creating, we allow our administrators to upload a CSV file with certain data that gets parsed and entered into our databases (all appropriate error handling is occurring, etc.).

As part of an upgrade to .NET 4.5, I had to update a few aspects of this code, and, while I was doing so, I ran across this answer of someone who is using MemoryStream to handle uploaded files as opposed to temporarily saving to the file system. There's no real reason for me to change (and maybe it's even bad to), but I wanted to give it a shot to learn a bit. So, I quickly swapped out this code (from a strongly-typed model due to the upload of other metadata):

HttpPostedFileBase file = model.File;
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/Uploads"), fileName);
file.SaveAs(path);

CsvParser csvParser = new CsvParser();
Product product = csvParser.Parse(path);

this.repository.Insert(product);
this.repository.Save();

return View("Details", product);

to this:

using (MemoryStream memoryStream = new MemoryStream())
{
    model.File.InputStream.CopyTo(memoryStream);

    CsvParser csvParser = new CsvParser();
    Product product = csvParser.Parse(memoryStream);

    this.repository.Insert(product);
    this.repository.Save();

    return View("Details", product);
}

Unfortunately, things break when I do this - all my data is coming out with null values and it seems as though there is nothing actually in the MemoryStream (though I'm not positive about this). I know this may be a long shot, but is there anything obvious that I'm missing here or something I can do to better debug this?

Community
  • 1
  • 1
JasCav
  • 34,458
  • 20
  • 113
  • 170

2 Answers2

6

You need to add the following:

model.File.InputStream.CopyTo(memoryStream);
memoryStream.Position = 0;

...

Product product = csvParser.Parse(memoryStream);

When you copy the file into the MemoryStream, the pointer is moved to the end of the stream, so when you then try to read it, you're getting a null byte instead of your stream data. You just need to reset the position to the start, i.e. 0.

Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
2

The problem I believe is your memoryStream has it's position set to the end, and I'm guessing that your CSVParser is only processing from that point onwards which there is no data.

To fix you can simply set the memoryStream position to 0 before you parse it with your csvParser.

memoryStream.Position = 0;
Kyle C
  • 1,627
  • 12
  • 25