.Net MVC 2, вернуть файл, который содержит не-ASCII символы в имени файла - PullRequest
1 голос
/ 13 сентября 2011

Я работаю над задачей экспорта данных, которая должна быть в состоянии экспортировать на любой язык. Все языки, в которых используются строго символы ASCII, работают нормально, но когда я иду на экспорт данных на восточных языках, возникает следующее исключение: «В заголовке письма обнаружен недопустимый символ». После небольшого исследования я определил, что это Это связано со спецификацией RFC 2183, в которой говорится, что «Значения параметра длиннее 78 символов или содержащие символы, не входящие в ASCII, ДОЛЖНЫ быть закодированы, как указано в [RFC 2184]»

Я прочитал оба этих документа, и они не сильно помогли. Я понимаю, что существует необходимость отправки данных в кодировке UTF-8, чтобы найти файл. Тем не менее, это приводит к тому, что имя загруженного файла отображается как кодированный UTF-8. На данный момент я кодирую имена файлов в UTF, используя функции, которые я опубликую ниже. (Все это в 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();
    }

И файл возвращается в следующей функции:

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

Строго говоря, это работает. Однако полное имя файла заканчивается в кодировке UTF, когда достигает пользователя. Я ищу способ передать этот ранее существующий файл пользователю, чтобы он мог сохранить свои символы, не входящие в ASCII.

Любая помощь приветствуется.

1 Ответ

0 голосов
/ 20 декабря 2011

Похоже, что это не кодировка UTF-8, а вариант кодировки URI на основе utf-8. Мы могли бы исправить это с помощью:

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).

...