karan k
karan k

Reputation: 967

System.IO.File.Exists(fpath) returns false in Chrome and Firefox

I have the following code which works in Internet Explorer, but not in Firefox and Google Chrome.

public ActionResult LogoForm(HttpPostedFileBase file)
{
    if (file != null)
    {
        string fpath = file.FileName;
        if (System.IO.File.Exists(fpath))
        {
            // Logic comes here
        }
    }
}

In my View I have this:

@using (Html.BeginForm("LogoForm", "LogoEditor", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <text>Logo Image &nbsp;&nbsp;&nbsp;</text>
    <input type="file" name="file" id="file" /> <text> &nbsp; &nbsp; &nbsp;</text>
    <input type="submit" name="upload" value="Upload" />
}

In case of any file in Firefox and Chrome, the line 'if (System.IO.File.Exists(fpath))' always returns false! It doesn't find the file. Why so?

Upvotes: 1

Views: 3591

Answers (5)

Jesse
Jesse

Reputation: 8393

Rather than attempting to use the path of what was sent into the controller (as others have mentioned, supported locally by Internet Explorer only), try the following:

if (file != null && file.ContentLength > 0) 
{
    // The fielname
    var fileName = Path.GetFileName(file.FileName);

    // Store the file inside ~/App_Data/uploads folder for example
    var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);

     // Other stuff    
}

Upvotes: 1

devio
devio

Reputation: 37205

Internet Explorer posts the original filename including the path for a type="file" input control, whereas other browsers just deliver the filename.

Since the browser usually does not run on the server, why do you want to check whether the full filename exists on the server?

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1500105

When you say it returns false "in" Chrome and Firefox - it's not the browser executing your code, of course. It's the server executing code in response to a request.

Presumably they're giving the filename in some different format to IE. You should log what file.FileName is, and that should make it clearer what's going on. It's slightly alarming to see that you're just taking the exact filename posted by the browser - in the case of a relative filename it's probably not relative to the directory you want, and in the case of an absolute filename you're comparing whether a file that exists on the client computer exists in the same place on the server - which again, isn't a good idea.

EDIT: It sounds like you're interested in whether or not the file really exists on the client computer. Two points:

  • You can't tell, and File.Exists certainly isn't the right check. That's running on the server which doesn't have access to the client's file system, thank goodness.
  • You shouldn't care. Maybe the client doesn't really have a local file system - maybe it's simulating it from some cloud storage, or something like that. You're not meant to care about that: you've been given a request with some information about a "file upload" and that's what you should care about.

Upvotes: 2

Anthony Shaw
Anthony Shaw

Reputation: 8166

Just to add to what people have already said, if the user has added the file to the file input control, it must exist on the client's computer somewhere, since they've added it to the form on the website.

Once they've clicked submit, the HttpPostedFileBase inputstream property contains the bytes of the file, the filename is simply given so that you know what the name of the file is that was uploaded. As others have suggested use Path.GetFilename(string) to retrieve only the filename without directory path (if provided) and save that to your server. Generally, I will append some sort of timestamp to the file as to not overwrite a previous upload

Upvotes: 1

Darin Dimitrov
Darin Dimitrov

Reputation: 1038720

file.FileName contains the file path on the client computer, not on the server. You should not use it on the server. The reason this works in IE is because IE happens to send the full path to the file to the server and since you are running both the client and the server on the same machine it works. Chrome and FF for security reasons never send the file path. IIRC they send a dummy path to the server that doesn't exist anywhere. This won't work with IE neither when you deploy your application in IIS and access it remotely.

You should never rely on the path portion of file.FileName. You should only extract the filename and then concatenate it with some path on the server:

Like for example

[HttpPost]
public ActionResult LogoForm(HttpPostedFileBase file)
{
    if (file != null)
    {
        string path = Path.GetFileName(file.FileName);
        string fileName = Path.Combine(Server.MapPath("~/App_Data"), path);
        if (File.Exists(fileName))
        { 
            // logic comes here
        }
    }
}

I would also recommend you checking out the following blog post about uploading files in ASP.NET MVC.

Upvotes: 6

Related Questions