Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Uploading a File: MemoryStream vs. File System

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?

like image 416
JasCav Avatar asked Apr 02 '13 21:04

JasCav


1 Answers

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.

like image 167
Chris Pratt Avatar answered Sep 28 '22 08:09

Chris Pratt