FileUpload Control Doesn’t Give Full Path….HELP!!!!

I’ve answered this question about five times in the last few days at the forums. It’s getting tedious so I thought I’d make a blog post about it.

Issue:

The FileUpload control has a FileName property. In FireFox (FF) and some other standards compliant browsers, the filename only holds the name of the file. It does NOT hold the full path. In some versions of Internet Explorer (perhaps all versions, but at least up until v7), the FileName property holds a full path. Hence, people see discrepancies among the browsers in terms of the FileName property. A lot of you guys are asking how to get the full path from the file upload control.

What does the FileName property do?

The FileName property holds the name of the uploaded file. In FF, it holds only the file name. In IE7 and earlier (possibly IE8 too – I’ll refer to all of them as IE from here on) it holds THE FULL PATH TO THE FILE ON THE CLIENT’S MACHINE. Read that again, and again, and one more time. It’s the full path of the uploaded file on the client’s machine. NOT THE PATH OF THE UPLOADED FILE ON THE SERVER.

WHOAH…Hang on a minute…the client machine?

Yes. It holds the path to the uploaded file on the machine of the user using the website, not the server. It’s the path you see in the file upload controls text box. It’s the user’s local path to the file. The user may have an M drive with a pics folder. The FileName property will then hold something like M:/pics/pic1.png. The server may not even have an M drive with a pics folder.

That SUCKS!!!! What good is that?

This is a decision made by the creators of IE. It was done to enable easier automation of intranet apps where file operations across the network could be accomplished easier.

Hmmm…Why do them FF guys not support it?

Them FF guys think that letting the server know about the folder structure of a user’s machine is a serious breach of security. For example, if for some reason you had a pic with the path D:\My Racy Photos With X\pic112.jpg (which may be an official photo for whatever reason) and you upload that to the office server, you wouldn’t want your boss (or anyone else) to know that you have a folder called “My Racy Photos With X” on your pc. That’s private info and would be embarrassing if leaked. The worst case scenario would be a few blushes. Now think if you had a folder with some secure info in the name. Even if the contents were secure and not the folder name, you wouldn’t want to make it easier on anyone to get to them. Hence, this can be considered a security flaw.

Ok…err…So where does my uploaded file go to?

The uploaded file is uploaded to a temp location on the server. If you process it, fine. If not, it’s purged (read deleted).

Wait…how do I store the uploaded file then?

Simple. The FileUpload control has a SaveAs(string path) method. You can use that method to save the file to any path using any filename you want. Just make sure asp.net has permissions to write to that path. So, you can do something like this to save the uploaded file to the uploads folder in the root of your website:

fileUpload1.SaveAs(Server.MapPath(“~/uploads/”) + System.IO.Path.GetFilename(fileUpload1.FileName));

[The reason I’m doing a Path.GetFileName is to ensure that even in IE, I only pass the filename and not the entire client side path to the SaveAs method.]

If you wish to provide a different username, you can do that just by changing the parameter. If you wish to append a unique key to each upload, you can use something like Guid.NewGuid().ToString() –or any other technique you want.

Ok smarty pants…saving to the file system is old school. I wanna save it to a database as an array of bytes. If I don’t have the file location, how do I get the array of bytes? How do I use File.ReadAllBytes if I don’t have a path? Huh? Huh?

Glad you asked. The FileUpload control ha a FileBytes property that gives you an array of bytes with all the contents of the file. Just use that.

Now I want to do some processing on the uploaded file. How do I get a Stream without the path?

The FileUpload control has a FileContent property that gives you a stream to the file. You can use it like this:

Stream str = fileUpload1.FileContent;
StreamReader sr = new StreamReader(str);
string contentText = sr.ReadToEnd();

What about the normal <input type=file> file uploads? I don’t like the FileUpload control. Can I get the full filename from that?

The FileUpload control uses the <input type=’file’> tag behind the covers. You’ll get no added info about the path from using a basic <input type=’file’> tag. The same restrictions apply. Using the input tag, you’ll have to do a bit more work to get to the file bytes. You can get to each uploaded file in a postback by using Request.Files. This will give you every HttpFileUpload in the request, regardless of if you use a <input type=’file’> or a FileUpload control. If using the input tag, you can set the runat=’server’ and id attributes to access it from server side code. You can then access it’s PostedFile in postback. Each object in Request.Files and each PostedFile of each <input type=’file’ runat=’server> and also each PostedFile of each FileUpload is of type HttpFileUpload. That class also has a SaveAs method that does exactly what you’d expect it to. If you need to access the stream, then it has an Inputstream property. You can use it to read the contents using a StreamReader as I’ve shown above. If you need to access the bytes, the following code will help [please note that HttpFileUpload does not have any direct way to give you all the bytes in a byte array, like the FileUpload control does]:

HttpPostedFile file = Request.Files[0]; //you can use inputid.PostedFile too
Stream str = file.InputStream;
byte[] bytes = new byte[file.ContentLength];
str.Read(bytes, 0, file.ContentLength);

After that, bytes will hold the binary content of the file.

Hope that helps.

26 Comments

  • Whoa!! :)
    your writing style is really impressive. Keep them coming.

  • Thanks budugu. I fully intend to :)

  • Thanks a lot, exactly what I needed!!

    And I also likes the style :)

  • This is really a good blog and the style of your writing is also grate and makes blog more interesting, keep it up. but you have not mentioned how to get file using javascript, which is the question most people are asking.

  • @Lateef:
    I ahevn't mentioned how you get to the file using javascript coz you can't get to the file using javascript. Javascript isn't allowed anywhere near files. This is a security measure and is the reason you can't upload / download files via javascript (and on AJAX requests). It's not specific to .net - javascript simply isn't allowed access to files.

  • Good article thanks.

  • Thanks for your tips.
    I just run into this problem yesterday.
    One web application that reads in a file from a client stopped working and I was puzzled.
    But I was saved by your blog.
    Thanks to you from Japan.

  • Many thanks! Helped out a lot!

    I used this blog to come to the discovery that FF and IE read the filenames differently. And the IE version was the one i needed! Thanks again and keep up the good work!

  • Wrote a delphi package where you can select a file ( manuals ,faq etc) and upload it to ( intranet)webserver via ftp , also stores info about file in mysql to be used in a search .

    one of the thing we save is the orignal path BECAUSE if the user makes a new version of his file he needs to be able to upload it ......Reading this post it seems that doing this using PHP or ASP is become impossible

  • I am using IE 8 and FF, the FileName property only gives me the name of the file and its extension. I need the full path name and still can't figure how to get it.

  • You CAN'T be guaranteed the full path name. The path name is the path of the uploaded file on the client's machine. You shouldn't need that info. Giving u access to the client's folder structure could be considered a security breach.

  • I am in the process of migrating my application from Visual Studio 2003 .net 1.1 to Visual Studio 2008 .net 3.5. windows 2008

    When i add a break point in the debugger to the first line of code to be caught on fileupload.filereceived nothing is caught by the debugger.

    the file is actually saved to the path but there is some other error that i cant seem to capture.

    the actual error i am trying to capture is
    Object of type 'System.String' cannot be converted to type 'System.Web.VirtualPath'

    any ideas?

  • Thanks a lot for your guidence

  • Awesome and very simple code examples. I love it. Keep up the fantastic work!!!!

  • I try on click site read file and pass as AJAX POST to .ashx.cs. FF don't give me the full path, when I on ashx.cs to read the file, error out.
    It's easy to figure out from code behind .cs file, but still not resolve my problem.
    I need the full path of image file to pass to handler page by parameter.
    HELP!!

  • This article was extremely helpful...Thank you SO much! :-)

  • IIRC IE8 has the FF feature too now.

  • describe me how to upload dynamically and and pass a file path to server.

  • I am using jquery fileupload plugin to upload the file (images) asynchronously. In my case i need the full path to the file on client machine, so that i can show the preview of the image on the spot & in the background i can upload the image. (now whats happening is the user has to wait till the image uplods to server and loaded on browser to see it.

    This application will be used by very minimal (say 2 to 3) users so i am looking for any browser settings which will give u the access to full path.

  • How can we use a fileupload control with this, instead of hard coding the client file path?

  • hi how can i acces the file stored in the local folder that recend updated

  • Guys...
    Below code worked .. use it

    HttpPostedFileBase file = Request.Files[strfile];

    string fileName = file.FileName.ToString();

    string extention = fileName.Substring(fileName.LastIndexOf('.') + 1, fileName.Length - 1 - fileName.LastIndexOf('.'));

    if (extention == "jpeg" || extention == "jpg" || extention == "png" || extention == "gif")
    {

    //-----------------------------------------
    Stream inputStream = file.InputStream;
    System.Drawing.Image image = System.Drawing.Image.FromStream(inputStream);
    try
    {
    //int fileLength = Convert.ToInt32(imag.Length);
    int fileWidth = image.Width;
    int fileHeight = image.Height;
    } .........

    hope this help

  • Its great ..

    bt if i want to save a full directory then it will not work..

    so can u please guide me in this regard.

  • I know I cannot access environmental SERVER variables with javascript (client-side), but how can I provide the user with a preview of the uploaded image using the onchange event if I cannot access the temporary uploaded path? He has to submit the form in order for me to get that information or....?

  • Hi

    Thanks to provide this blog.
    I really appriciate if you can provide a simple code to and steps to get the file path as well as file content in servlet.

    Thanks
    Vidhi

  • FileUpload Control Doesn’t Give Full Path….HELP!!!!

Comments have been disabled for this content.