1

This is my MVC controller to upload an image. I'm trying to check if the file exists, then deleting the old one and saving the new one if it does. I get the error at System.IO.File.Delete() telling me the file is in use already, but I can't figure out where I left it open and how I might close it.

[HttpPost]   
public ActionResult UploadImage(int? id, HttpPostedFileBase file, EmployeeViewModel employee)
{
    Employee employeeData = db.Employees.Find(id);
    if (file != null && file.ContentLength > 0)
    {
        // Assemble File Path/Extension String
        string[] fileSplit = file.FileName.Split('.');
        string extension = fileSplit[1];
        var fileNameNew = "employeeImage-" + id + "." + extension;
        var path = Path.Combine(Server.MapPath("~/Content/employeeImages/"), fileNameNew);

        var fileExists = System.IO.File.Exists(path);

        if (fileExists)
        {
            System.IO.File.Delete(path);
            file.SaveAs(path);
        }
        else
        {
            file.SaveAs(path);
        }

    }
    return RedirectToAction("Edit", new { id = id });
}
RB.
  • 36,301
  • 12
  • 91
  • 131
ttante
  • 55
  • 5
  • have you tried to restart your web server? – sowen Jan 05 '16 at 15:44
  • Yeah I even rebooted my machine – ttante Jan 05 '16 at 15:46
  • this might sound stupid, but I will ask anyway. where did you choose the source image to upload? I haven't done ASP.NET for a long time, so I don't remember how to do upload like that, but in the past, I always have to write a httphandler to deal with file upload. another quick thought, you don't have to delete the existing file, just save it to a new file, adding a timestamp, so you keep the employee old photos all the time (see if that works) – sowen Jan 05 '16 at 15:51
  • I add it via a webpage and a file input element. I'll consider trying to skip deleting and going with a timestamp, I was trying to use a simple naming convention of just 'employeeImage-ID.extension' to make file retrieval easy, but I could add a timestamp and search for the most recent one with the matching ID upon retrieval. – ttante Jan 05 '16 at 16:00
  • 2
    Is there any web methods or other code that retrieve the image (not the url) that leave it open as a stream? You can also use a command line program named `handle` by `sysinternals` that can show you which process has a file open. You can use this for manual troubleshooting to figure out what has the file open. https://technet.microsoft.com/en-us/sysinternals/handle.aspx – Igor Jan 05 '16 at 16:30
  • Yes, I'm seeing this comment just after I realized that my issue had to take place inside of the GET request controller that serves the page to which I was trying to post to since I couldn't find any issue with my POST controller. – ttante Jan 05 '16 at 18:16
  • @ttante - glad to help. I posted my comment as an answer. – Igor Jan 05 '16 at 20:05

3 Answers3

1

There is probably a (web) method (like a GET request) or other code that retrieves the image (not the url) that leaves it open as a stream.

Igor
  • 60,821
  • 10
  • 100
  • 175
0

The most likely answers would be that either:

  • The file is located on a network share and someone else is genuinely using it (is it a virtual directory?).
  • IIS/ your web server is locking the file (see Does IIS 6/7 lock image files whilst they're being served?
  • You are uploading the same file as you are writing to (apologies if this sounds patronising but you need to cover all options!)
Community
  • 1
  • 1
strickt01
  • 3,959
  • 1
  • 17
  • 32
0

Since I couldn't find the issue with my POST request, I realized it had to be in the GET request that was taking me to that page. Turns out I was calling Image.FromFile() and not closing it in that GET request.

ttante
  • 55
  • 5