Carl R
Carl R

Reputation: 8214

Valid filenames (for download) in IE?

I have an action in aspnet mvc that returns a FileContentResult. I have noticed that when the fileDownloadName contains umlauts (ie åäöü) Internet Explorer can't read the file name at all.

I have tried UrlEncoding:

return this.File(document.Content, contentType, Server.UrlEncode(document.Name));

but then all spaces are replaced by plus signs (+).

Is there a way to get unicode file names work with IE (keeping the original file name intact)?

This is what I'm currently using as a hack:

return this.File(
    document.Content, 
    contentType, 
    Server.UrlEncode(document.Name).Replace('+',' '));

(This renders space as an underscore in IE)

Upvotes: 2

Views: 4457

Answers (4)

Remy
Remy

Reputation: 12703

I've tried the encoding stuff, worked well in Chrome and FF, but had trouble with IE. So I just came up with my own cleaning routine. Basically it's just a mapping table, since we don't just want to remove all special 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
    };

I've wrapped it into a function, you can find the code here:
http://remy.supertext.ch/2012/08/clean-filenames/

Upvotes: 0

bobince
bobince

Reputation: 536369

  1. UrlEncode is misleadingly-named, it is only for form data. You would want UrlPathEncode instead which would solve the + problem. See this question for background.

  2. However in any case URL-encoding is the wrong thing to do here, as you aren't constructing a URL. The fact that it works in IE is a bug, which is why you get %-sequences in other browsers.

Unfortunately, there is no reliable cross-browser way to get non-ASCII characters into a Content-Disposition filename parameter. In theory it might have been possible using RFC 2331 rules, but even then the spec is arguable and the reality is nothing supports it. See this question for background.

Is there a way to get unicode file names work with IE (keeping the original file name intact)?

Drop the filename parameter from the Content-Disposition header and instead include the filename as a trailing path part of your script's address, where it's quite valid to use URL-encoding (UTF-8 and UrlPathEncode). eg for someaction controller:

http://www.example.com/someaction/åäöü.txt
http://www.example.com/someaction/%C3%A5%C3%A4%C3%B6%C3%BC.txt

All browsers will offer to save the resulting file as åäöü.txt.

Upvotes: 6

Mariusz
Mariusz

Reputation: 3154

For responses I use solution from this thread. Maybe you could try to use it like

return this.File(
  document.Content,
  contentType,
  "\"" + Server.UrlEncode(document.Name) + "\"");

or

return this.File(
  document.Content,
  contentType,
  "\"" + document.Name + "\"");

Upvotes: 1

Mario
Mario

Reputation: 36487

Just encode the file name the way you do, but then replace all + with %20. Untested, but should work.

Upvotes: 0

Related Questions