Downloading file with “;” or “#” in file name ruins filename

I have a file named AttachmentDownload.aspx and inside Page_Load method have such code which offers to download file. All names work correctly in IE except names which include “;” or “#”. They offer user to save the file under name “AttachmentDownload.aspx”. Is there a workaround for this?

Here is an example:

var fileName = Server.UrlPathEncode (";%.txt");
Response.AddHeader("content-disposition", String.Format("attachment;filename="{0}"", fileName));
Response.WriteFile(path);
Response.End();

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

All names work correctly in IE except names which include “;” or “#”.

I can’t reproduce the problem with ‘#’ but ‘;’ certainly does break it. As will ‘”’ and ‘’ (which you can have in a filename on Unix and which will break your quoted-string).

The “correct” solution for including out-of-band characters in an RFC822-family parameterised header such as Content-Disposition is defined in RFC1521: strings that cannot be contained in a ‘token’ should be wrapped in a quoted-string, which RFC2822 defines as having the ” and characters backslash-escaped, then surrounded in quotes.

RFC2231 then extends this with a very complicated way of including non-ASCII characters in header parameters, which in theory you would want to use to support Unicode characters.

In practice: HTTP is not really an RFC822-family specification, and none of this stuff works in regular browsers (except the backslash-escapes in Opera). There is no reliable way to get a Unicode Content-Disposition filename to the client, and your problem with ‘;’ is there not because of any escaping issue, but just because IE can’t parse parameterised headers for toffee (it splits on the next semicolon in the string even if it’s surrounded by quotes).

For reliable cross-browser filename-setting there are two approaches you can take in the real world:

  1. Remove anything offensive from filenames before putting them in a Content-Disposition header. This includes leading/trailing spaces/dots, most other punctuation and anything non-ASCII.
  2. Don’t specify a filename in the Content-Disposition header at all, and let the browser work out what filename to use from the last part of the URL. To stop it choosing “AttachmentDownload.aspx”, you can put whatever you like as a trailing URL part, eg.:

    http://www.example.com/AttachmentDownload.aspx/Foo%23Bar

This requires you encode most punctuation using plain URL encoding and Unicode characters with UTF-8, but at least you can get the characters in. The above results in a file download prompt for ‘Foo;Bar’.

Note that even though you can encode Windows-unfriendly characters like ‘”’ in a URL path part like this, for downloaded files it is best not to, because IE will respond by trying to save the file using a ‘”’ in the filename, and will silently and mysteriously fail in response.

Method 2

I started to just clean my filenames of all special characters. I’ve come up with a mapping table that should map most of the commonly used chars.

//http://www.pjb.com.au/comp/diacritics.html
private static string[,] CharacterReplacements = { 
    { " ", "-"},
    { "&", "-"},
    { "?", "-"},
    { "!", "-"},
    { "%", "-"},
    { "+", "-"},
    { "#", "-"},
    { ":", "-"},
    { ";", "-"},
    { ".", "-"},

    { "¢", "c" },   //cent
    { "£", "P" },   //Pound
    { "€", "E" },   //Euro
    { "¥", "Y" },   //Yen
    { "°", "d" },   //degree
    { "¼", "1-4" }, //fraction one-quarter
    { "½", "1-2" }, //fraction half    
    { "¾", "1-3" }, //fraction three-quarters}
    { "@", "AT)"}, //at                                                  
    { "Œ", "OE" },  //OE ligature, French (in ISO-8859-15)        
    { "œ", "oe" },  //OE ligature, French (in ISO-8859-15)        

    {"Å","A" },  //ring
    {"Æ","AE"},  //diphthong
    {"Ç","C" },  //cedilla
    {"È","E" },  //grave accent
    {"É","E" },  //acute accent
    {"Ê","E" },  //circumflex accent
    {"Ë","E" },  //umlaut mark
    {"Ì","I" },  //grave accent
    {"Í","I" },  //acute accent
    {"Î","I" },  //circumflex accent
    {"Ï","I" },  //umlaut mark
    {"Ð","Eth"}, //Icelandic
    {"Ñ","N" },  //tilde
    {"Ò","O" },  //grave accent
    {"Ó","O" },  //acute accent
    {"Ô","O" },  //circumflex accent
    {"Õ","O" },  //tilde
    {"Ö","O" },  //umlaut mark
    {"Ø","O" },  //slash
    {"Ù","U" },  //grave accent
    {"Ú","U" },  //acute accent
    {"Û","U" },  //circumflex accent
    {"Ü","U" },  //umlaut mark
    {"Ý","Y" },  //acute accent
    {"Þ","eth"}, //Icelandic - http://en.wikipedia.org/wiki/Thorn_(letter)
    {"ß","ss"},  //German

    {"à","a" },  //grave accent
    {"á","a" },  //acute accent
    {"â","a" },  //circumflex accent
    {"ã","a" },  //tilde
    {"ä","ae"},  //umlaut mark
    {"å","a" },  //ring
    {"æ","ae"},  //diphthong
    {"ç","c" },  //cedilla
    {"è","e" },  //grave accent
    {"é","e" },  //acute accent
    {"ê","e" },  //circumflex accent
    {"ë","e" },  //umlaut mark
    {"ì","i" },  //grave accent
    {"í","i" },  //acute accent
    {"î","i" },  //circumflex accent
    {"ï","i" },  //umlaut mark
    {"ð","eth"}, //Icelandic
    {"ñ","n" },  //tilde
    {"ò","o" },  //grave accent
    {"ó","o" },  //acute accent
    {"ô","o" },  //circumflex accent
    {"õ","o" },  //tilde
    {"ö","oe"},  //umlaut mark
    {"ø","o" },  //slash
    {"ù","u" },  //grave accent
    {"ú","u" },  //acute accent
    {"û","u" },  //circumflex accent
    {"ü","ue"},  //umlaut mark
    {"ý","y" },  //acute accent
    {"þ","eth"}, //Icelandic - http://en.wikipedia.org/wiki/Thorn_(letter)
    {"ÿ","y" },  //umlaut mark
    };

Or you can get the whole code here:

http://remy.supertext.ch/2012/08/clean-filenames/

Let me know if you find chars that are missing.

Method 3

Filename with special symbols(e.g: space; # @ ! $ ) or Non-Unicode characters either cannot be supported by some browsers or cause incorrect filename in client machine.
Here is an article by a Chinese called chanext, he gave a perfect way to solve this problem:
this article gave a sample code(written with c#) to show how to get perfect solution to this problem in the all four popular browsers (IE; Opera; Firefox and Chrome)
the filename “Microsoft.Asp.Net.doc” and “F ile;;[email protected]%#^&y.doc” can both be output correctly using the way the author provided in this article.

http://ciznx.com/post/aspnetstreamdownloaddisplaynonunicodespacechar.aspx

Method 4

UrlPathEncode only encodes the “Path” portion of a URL-like formed string, try using
Server.UrlEncode or HttpUtility.UrlEncode.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x