eKek0
eKek0

Reputation: 23329

How do I encode a file name for download?

When the file name is "Algunas MARCAS que nos acompañan" ASP.NET MVC raise an System.FormatException when I try to download that file. But if the file name is "Asistente de Gerencia Comercial" it doesn't.

I guess this is because something related to UTF-8 encoding, but I don't know how to encode that string.

If I'm right, how can I encode the string in UTF-8 encoding? If I'm not right, what is my problem?

Upvotes: 21

Views: 30472

Answers (9)

tomRedox
tomRedox

Reputation: 30563

We had an issue where Chrome was changing filenames that contained underscores to the name of the page the file was being downloaded from.

Using HttpUtility.UrlPathEncode(filename) as suggested by Furkan Ekinci in the comments fixed it for us.

Upvotes: 2

Matt Roy
Matt Roy

Reputation: 1535

The only trick that works (in all browsers) for me is:

Dim headerFileName As String = IIf(Request.Browser.Browser = "InternetExplorer" Or Request.UserAgent.Contains("Edge"), Uri.EscapeDataString(file.Name), file.Name)
Response.AddHeader("Content-Disposition", "attachment; filename=""" + headerFileName + """")

Upvotes: 1

ZZ Coder
ZZ Coder

Reputation: 75496

I encode file name like this for downloading,

HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename= " + HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8));

Upvotes: 28

ashkan
ashkan

Reputation: 99

instead of using httpUtility that replaces the spaces in the file name with "+" using the following code resolve the problem:

string attachment = String.Format("attachment; filename={0}",Server.UrlPathEncode(file.Name.TrimEnd()));
Response.AddHeader("Content-Disposition", attachment);

please note that if you retrieve file name from data set you may need trim the name first! you have to also add the following lines of code in advance:

Response.Charset = "utf-8";
Response.HeaderEncoding = UnicodeEncoding.UTF8;
Response.ContentEncoding = UnicodeEncoding.UTF8;

Upvotes: 0

ashkan
ashkan

Reputation: 99

note that using UTF encoding replaces the spaces in the file name into '+', using either the following codes produce the same results:

HttpUtility.UrlEncode("é", System.Text.Encoding.GetEncoding("ISO-8859-1"))
HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8)

Upvotes: 0

TJB
TJB

Reputation: 13497

Also: HttpUtility considered harmful:
http://serialseb.blogspot.com/2008/03/httputilityurlencode-considered-harmful.html

I'm just going to punt and replace " " with "_" and call it a day =)

Upvotes: 0

Julian Reschke
Julian Reschke

Reputation: 42075

This issue has been known for years. As far as I can tell, there currently is no interoperable way to do this, so the answer is to only support one set of browsers, or to do User Agent sniffing.

Test cases and links at: http://greenbytes.de/tech/tc2231/

Upvotes: 1

John Fisher
John Fisher

Reputation: 22727

I recently fought with this a bit, having many potential languages being used for the file names (Chinese is good to test with). Here is something close to what I ended up with (other implementation details excluded):

HttpUtility.UrlEncode("é", System.Text.Encoding.GetEncoding("ISO-8859-1"))

Upvotes: 0

eKek0
eKek0

Reputation: 23329

Based on ZZ Coder answer, and because I'm using FileResult, I decided to encode the file name as:

HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8)

Upvotes: 7

Related Questions