How to download file from fileserver where filename contains equal sign?

radix

New member
Joined
Sep 21, 2015
Messages
3
Programming Experience
10+
I am trying to download a file from a fileserver that has contains an equal sign but it is being stripped out. I have the following method in my controller (see code below).

Note that in the highlighted line of code surrounding the filename with double-quotes works fine for other special characters ($, #, @, &, etc) but equal signs are stripped out.


Is there something special I have to do, some way to escape the equal sign to make sure the downloaded file name retains the equal sign?


Thanks,
Brad

---------------------------------------------

protected FileStreamResult StreamFileToHttpResponse(Stream stream, string fileName, bool streamRawFile = false)
{
FileStreamResult nullResponse = null;
if (stream != null && !string.IsNullOrEmpty(fileName))
{
//Identify MimeType and Return to Browser as an Attachment
// IMPORTANT- Browser Determines How to Handle Attachments:
// IE may present Save Dialog Box
// Chrome does not present Save Dialog Box, only immedate download of file.
string mimeType = MimeMapping.GetMimeMapping(fileName);
if (!streamRawFile)
{
Response.AppendHeader("Content-Disposition", "attachment; filename="" + fileName + """);
Response.AppendHeader("X-Download-Options", "noopen");
}
return File(stream, mimeType);
} else
{
return nullResponse;
}
}
 
Equal sign is a plain Ascii char, so no escaping should be necessary for such char in that header. This article Content-Disposition headers in .NET - Softwire suggest two alternatives to escaping other chars yourself, using Mime.ContentDisposition class (will escape fully), and the File method with fileDownloadName parameter (generates escaped Content-Disposition header also). Neither will do anything special for equal signs in file names.

Still I found the problem you describe to happen when there is a space char before and after the equal sign (never with either one), and I can see the header is always correct, so I think this is a browsers bug. I also found that replacing spaces with %20 fixed it, this can be achieved with Server.UrlPathEncode(fileName). This seems to work in all latest browser versions of IE, Edge and Chrome, but not Firefox. I also noticed the problem does not occur in any browser (including Firefox) when using ContentDisposition class or File(...,fileDownloadName) method when these actually apply special encoding.

Fiddler debugger could help you reviewing how the requests are passed, but maybe not much since browser apparently handle thing each their own way anyway, and you can also see the actual filename used when saving your tests. It seems though, using UrlPathEncode and writing your own header in the form that File(...,fileDownloadName) produces should be a catch-all. Example when file name: test = test.txt
Content-Disposition: attachment; filename*=UTF-8''test%20=%20test.txt
 
Thanks JohnH! Replacing spaces with %20 did the trick on the equal sign. Now I have two more strange character issues. I did a query in the DB to find all the filenames that have special characters, created one file with all of those special characters, did some testing and the results of which are:

ORIGINAL FILE NAME
This is a weird _ = & # @ , ; ( ) - ' ~ + [ ] filename.txt


RESPONSE HEADER
{Server=Microsoft-IIS%2f10.0&X-AspNetMvc-Version=2.0&Content-Disposition=attachment%3b+filename%3d%22This%2520is%2520a%2520weird%2520_%2520%3d%2520%26%2520%23%2520%40%2520%2c%2520%3b%2520(%2520)%2520-%2520%27%2520%7e%2520%2b%2520%5b%2520%5d%2520filename.txt%22&X-Download-Options=noopen}


CHROME RESULT - Tilde converted to dash
This is a weird _ = & # @ , ; ( ) - ' - + [ ] filename.txt


IE RESULT - Pound sign converted to underscore
This is a weird _ = & _ @ , ; ( ) - ' ~ + [ ] filename.txt



If you know how to handle these two issues then you would be my new best friend. :p

Thanks,
Brad
 
It looks like something is wrong with your Content-Disposition string, but could where you copied it from. Use the form I posted attachment; filename*=UTF-8'' + encoded filename, but use Uri.EscapeDataString to encode the filename and not Server.UrlPathEncode that I said first. This will produce correct results in IE/Edge/Firefox, but in Chrome you will have to accept tilde replaced as hyphen, see Issue 479419 - chromium - Character tilde was converted to hyphen for downloaded filename on Chrome browser v42
There's no pound sign in your file name, but both number sign and pound sign will be ok.
 
Back
Top Bottom