1

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 = new 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.

4

1 回答 1

0

这似乎不是 UTF-8 编码,而是基于 utf-8 的 URI 编码的变体。我们可以通过以下方式修复它:

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();
}

您需要在此处捕获它认为特殊的任何其他字符以及 % 。如果这些特殊字符与 URI 的特殊字符相同,则可以使用Uri.EscapeDataString(s).

于 2011-12-19T22:17:56.407 回答