.Net MVC 2, return File that contains non-ASCII characters in the filename
I am working on a data export task that needs to be able to export in any language. All the languages that use strictly ASCII characters work just fine, but when I go for data exports in oriental languages, it throws the following exception: "An invalid character was found in the mail header" With a bit of research, I determined that this was due to the RFC 2183 spec which states that "Parameter values longer than 78 characters, or which contain non-ASCII characters, MUST be encoded as specified in [RFC 2184]"
I read both of these documents and they weren't much of a help. I understand that there is a need to send the data in UTF-8 encoding in order to locate the file. However, this makes the downloaded file name appear as encoded UTF-8. As of now, I am encoding the file names into UTF using the functions I will post below. (All of this is in C#, MVC2)
private static string GetCleanedFileName(string s)
{
char[] chars = s.ToCharArray();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < chars.Length; i++)
{
string encodedString = EncodeChar(chars[i]);
sb.Append(encodedString);
}
return sb.ToString();
}
private static string EncodeChar(char chr)
{
UTF8Encoding encoding = ne开发者_Go百科w UTF8Encoding();
StringBuilder sb = new StringBuilder();
byte[] bytes = encoding.GetBytes(chr.ToString());
for (int index = 0; index < bytes.Length; index++)
{
sb.AppendFormat("%{0}", Convert.ToString(bytes[index], 16));
}
return sb.ToString();
}
And the file is returned in the following function:
[ActionName("FileLoad")]
public ActionResult FileLoad()
{
string fileName = Request["fileName"];
//Code that contains the path and file type Removed as it doesn't really apply to the question
FileStream fs = new FileStream(filePath, FileMode.Open);
return File(fs, exportName, GetCleanedFileName(fileName));
}
Strictly speaking, this works. However, the entire file name ends up UTF-Encoded when it reaches the user. I'm looking for a way to pass back that pre-existing file to the user, such that it can keep its non-ASCII characters.
Any help is appreciated.
This seems to not be UTF-8 encoding, but a variant of utf-8-based URI Encoding. We could fix it up with:
private static string GetCleanedFileName(string s)
{
StringBuilder sb = new StringBuilder();
foreach(byte b in Encoding.UTF8.GetBytes(s))
{
if(b < 128 && b != 0x25)// ascii and not %
sb.Append((char)b);
else
sb.Append('%').Append(b.ToString("X2"));
}
return sb.ToString();
}
You'll need to catch any other characters it considers special as well as % here. If those special characters are the same as those special to URIs, you could just use Uri.EscapeDataString(s)
.
精彩评论