18

I'm having a problem with a file download where the download is replacing all the spaces with underscores.

Basically I'm getting a problem here:

Response.AddHeader("Content-Disposition", 
    "attachment; filename=" + someFileName);

The problem is that if someFileName had a space in it such as "check this out.txt" then the user would be prompted to download "check_this_out.txt".

I figured the best option would be to UrlEncode the filename so I tried

HttpUtility.UrlEncode(someFileName);

But it's replacing the spaces with plus signs, which stumped me. So then I just tried

HttpUtility.UrlEncode(HttpUtility.UrlDecode("%20"))

and the decode works properly and gives me a space, but the encode takes the space and then gives me the plus sign again.

What am I missing here, is this correct? If so, how should I properly encode spaces into %20's, which is what I need.

Joseph
  • 25,330
  • 8
  • 76
  • 125

5 Answers5

17

Basically both %20 and + are valid ways of encoding a space. Obviously the UrlEncode method has to pick one of the options... if it chose to do the other way, someone else would have asked why UrlEncode(UrlDecode("+")) returned "%20"...

You could always encode it, then just do a straight string replace on "+" for "%20". I think that would work...

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    Thanks Jon. The problem I'm seeing though, is that since it's choosing to go with the +, my file is showing up like "check+this+out.txt" instead of with spaces, which is the goal I'm trying to achieve. – Joseph Oct 13 '09 at 17:02
  • @Joseph: as Jon said, " " is replaced by "+"; when you tries to escape "+", you'll go with "%2B" – Rubens Farias Oct 13 '09 at 17:03
  • @Rubens I understand, but that still doesn't solve my problem. Either I encode it and my file ends up being called "check+this+out.txt" or I don't encode it and it gets called "check_this_out.txt". How do I get it to properly show the white space? – Joseph Oct 13 '09 at 17:12
  • Ok, so 5 years later, UrlEncode uses '+' but IIS 7 rejects '+' signs by default. What's the correct way to address this clash when creating URLs in server-side code? Do a second pass and replace the + signs with %20? – xr280xr Mar 13 '14 at 18:13
  • Thanks, I have also this problem with IE 11, and Jon's solution works for me. But Pay attention, first set the UrlEncoding, then the replace, like: 'Title.UrlEncoded.Replace("+", "%20")' works for me, but not 'Title.Replace("+", "%20").UrlEncoded' – IFink Aug 19 '14 at 17:12
  • "obviously the UrlEncode method has to pick one of the options": not at all. There could be *and should be* a parameter allowing the *caller* to pick one of the options. – phoog Mar 14 '19 at 19:20
  • @phoog: To clarify, I meant *when using the given method signature*. I agree that it would be desirable to have options there. – Jon Skeet Mar 14 '19 at 19:36
  • @JonSkeet There ought to be a badge for "remembering why you wrote something after nine and a half years!" :-) – phoog Mar 14 '19 at 20:03
9

I figured the best option would be to UrlEncode the filename

That's not the right way to put out-of-band characters in a header parameter such as Content-Disposition-filename, and only works (sometimes) in IE due to a bug. Actually it's a bit of a perennial problem: there is no right way.

If you need to put special characters in the downloaded filename, you can't do it reliably with Content-Disposition-filename. Instead, omit the ‘filename’ parameter from the Content-Disposition-attachment header, and leave the filename you want in the trailing part of the URL. In the absence of a filename parameter the browser will take it from the URL path, where URL-encoding is the right way to tackle special characters.

Community
  • 1
  • 1
bobince
  • 528,062
  • 107
  • 651
  • 834
7

Quoting from this link

I've come across this myself. If you are able to change the spaces to %20s then IE7 will convert them correctly. Firefox though will take them literally ( at least when using the Content-disposition header) so you will need to do this for requests from IE7 only.

We did the following in our app. ( a tomcat based document repository)

String userAgent = request.getHeader("User-Agent");
if (userAgent.contains("MSIE 7.0")) {
    filename = filename.replace(" ", "%20");    
}         
response.addHeader("Content-disposition",
    "attachment;filename=\"" + filename + "\"");
Hasan Fathi
  • 5,610
  • 4
  • 42
  • 60
mangokun
  • 5,493
  • 2
  • 15
  • 8
  • Thanks, I found this in a different article elsewhere with the same solution as you have. I'll probably end up having to do this, but it just feels wrong/dirty to me. Oh well. – Joseph Oct 13 '09 at 17:30
2

Hi I also faced same kind of problem when downloading the files having spaces in them.

Please see the link which best suites and gives the complete answer.

http://kb.mozillazine.org/Filenames_with_spaces_are_truncated_upon_download

For the sake of understanding I am just adding the ASP.net code how to solve this problem.

string document = @"C:\Documents and Settings\Gopal.Ampolu\My Documents\Downloads\" + "Disciplinary & Grievance Procedures..doc";
string filename = "Disciplinary & Grievance Procedures..doc";

Response.ContentType = mimeType;
Response.AddHeader("Content-Disposition", @"attachment; filename=""" + HttpUtility.UrlDecode(filename) + @"""");
Response.Flush();

From the above you can see that while adding header to the response, filename is enclosed with double quotes. Please make sure that the "filename" must be Decoded with UrlDecode.

Rup
  • 33,765
  • 9
  • 83
  • 112
Vedagopal
  • 21
  • 3
1

One more option is also there, if you can intimate clients about windows hotfix update available at following:

Windows Hotfix Update for IE white space issue

It is client side, so may not be applicable to all the scenarios but still an option if feasible.

Altaf Patel
  • 1,351
  • 1
  • 17
  • 28