Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading a HttpPostedFile before saving it saves a blank file in ASP.NET MVC

Before saving an uploaded csv file I want to check it will parse. When I was just saving the file everything was fine, now that I'm reading it first the file saved is blank.

Here is my action method

[HttpPost]
public ActionResult Import(HttpPostedFileBase file)
{
    // Check parse went ok
    using (var fileStream = file.InputStream)
    {
        if (!MemberFileParsingService.CheckFileWillParse(fileStream))
        {
            ViewBag.Message = "There was a problem with the file";
            return View();
        }
    }

    // Save file so we can work on it in next action
    file.SaveAs(Server.MapPath(fileName));

    return RedirectToAction("ImportMatch", new { club = ActiveClub.Url });
}

And here's my method that checks to see if the file parses ok. It uses CsvReader to read through the whole file to check there are no errors. CsvReader throws exceptions when it comes to bad bits of the file.

public static bool CheckFileWillParse(Stream fileStream)
{
    try
    {
        using (var reader = new StreamReader(fileStream))
        {
            using (CsvReader csv = new CsvReader(reader, false))
            {
                while (csv.ReadNextRecord()) { }
            }
        }
    }
    catch(Exception)
    {
        return false;
    }
    return true;
}

I think it's probably because it's trying to write the file using the same stream that is now at the end of the file. I don't know how to reset the stream though. I was hoping all my using statements would fix that problem.

So how can I reset the stream, or is that just a red herring?

Update: Found the length of the stream gets reset to zero after going through CheckFileWillParse so looks like resetting the stream is just a red herring and the stream is actually being blanked somehow.

like image 403
Richard Garside Avatar asked Dec 16 '10 15:12

Richard Garside


2 Answers

You have to rewind the stream (if possible). Once you are doing reading it, the current position is at the end of the stream, that is why the file is empty when you save it.

You can use either the Seek function or the Position property to do this (set it to 0). Not all stream types support this though.

If a stream type doesn't support it, you may need to write the file out to disk first, then run your test against it.

like image 98
Brian Ball Avatar answered Oct 14 '22 08:10

Brian Ball


Have you considered creating a copy of the stream to analyse, using Stream.CopyTo()?

like image 25
kim3er Avatar answered Oct 14 '22 10:10

kim3er