Путаница при декодировании URL - PullRequest
2 голосов
/ 03 августа 2009

У меня есть БД, которая ссылается на следующий URL:

http://en.wikipedia.org/wiki/Herbert_Gr%F6nemeyer

Однако, похоже, что это плохое кодирование URLE, вызывающее проблемы как с HttpUtility.UrlDecode (дает мне мусор), так и Uri.UnescapeDataString (UriFormatException). Мой браузер передает путь к Википедии без изменений (поэтому я предполагаю, что% F6 кодируется браузером) следующим образом:

GET / wiki / Herbert_Gr% F6nemeyer HTTP / 1.1

Википедия распознает и 301 перенаправляет на:

Расположение: http://en.wikipedia.org/wiki/Herbert_Gr%C3%B6nemeyer

Что здесь происходит? Есть ли в Википедии дополнительная фирменная кодировка?

РЕДАКТИРОВАТЬ: У меня есть локальная копия Википедии, я пытаюсь сделать перекрестную ссылку на этот URL. Статьи индексируются по названию, которое в этом случае будет: «Герберт Грёнемейер». Кто-нибудь может подсказать, как я перешел бы от "Herbert_Gr% F6nemeyer" к "Herbert Grönemeyer" в коде. Очевидно, подчеркивание здесь не является проблемой.

Ответы [ 2 ]

4 голосов
/ 03 августа 2009

% C3% B6 - правильная кодировка UTF-8 для ö (o-umlaut). Я бы предположил, что% F6 является побайтной копией байтового значения для некоторой локальной кодировки того же символа (например, из кодовой страницы 1252).

2 голосов
/ 03 августа 2009

Вот небольшой быстрый и грязный код, который я собрал вместе, чтобы понять это. Спасибо Йосипу за то, что он указал мне правильное направление:

    private string UrlDecode(string input)
    {
        string unescaped = null;
        try
        {
            unescaped = Uri.UnescapeDataString(input);
        }
        catch
        {
            unescaped = input;
            for (; ; )
            {
                var match = Regex.Match(unescaped, @"\%[A-F0-9]{2}");
                if (!match.Success)
                    break;
                byte b;
                try
                {
                    b = byte.Parse(match.Value.Substring(1), NumberStyles.HexNumber);
                }
                catch
                {
                    return HttpUtility.UrlDecode(input);
                }
                var replacement = Encoding.GetEncoding(1252).GetString(new[] { b });
                unescaped = unescaped.Substring(0, match.Index) + replacement + unescaped.Substring(match.Index + match.Length);
            }
        }
        return unescaped;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...