RedirectToRoute выполняет двойную кодировку «/» в параметрах, которые являются URL-адресами в routeValues - PullRequest
3 голосов
/ 06 сентября 2011

У меня проблема с кодировкой, с которой я не могу разобраться в отношении параметра на маршруте. По сути, он либо никогда URL не кодирует, либо double URL кодирует. Я просто хочу, чтобы это было в одном кодировке!

Вот маршрут, который я зарегистрировал:

routes.MapRoute("Scan", "Scan/{*url}", new { controller = "Scan", action = "Index" });

Теперь у меня есть действие контроллера, которое перенаправляет на этот маршрут. Для простоты, скажем, это выглядит так:

var url = "troyhunt.com/search";
return RedirectToRoute("Scan", new { url });

Полученный URL-адрес - «Scan / troyhunt.com / search» - обратите внимание, что косая черта после .com не была , не экранирована.

Теперь давайте попробуем это снова, но применим кодировку URL:

var url = HttpUtility.UrlEncode("troyhunt.com/search");
return RedirectToRoute("Scan", new { url });

На этот раз результирующий URL-адрес будет «Scan / troyhunt.com% 252fsearch» - обратите внимание, что косая черта была закодирована двойным образом. Если я установлю точку останова до перенаправления, я увижу метод UrlEncode, успешно кодирующий косую черту в% 2f.

Похоже, что редирект кодирует символ "%", но не "/". Если я тестирую с другими символами, обычно экранированными с помощью URL-кодировки (?, =), Кодировка работает просто отлично прямо из метода RedirectToRoute. Может ли это быть проблемой, если рассматривать косую черту как разделительный сегмент маршрута, а значит, не избежать его? Я что-то здесь упускаю?

Обновление: дополнительные сведения, комментарии и обходные пути обсуждаются в Направлять или не направлять, это вопрос .

1 Ответ

3 голосов
/ 07 сентября 2011

Если посмотреть на System.Web.Routing, похоже, что это происходит из-за того факта, что значения маршрутов не кодируются в URL с использованием HttpUtility.UrlEncode(value), а фактически "экранируются" с использованием Uri.EscapeUriString(value).

Код обидчика находится в System.Web.Routing.ParsedRoute:

// Dev10 601636 Work around Uri.EscapeUriString not encoding #,&
    private static string UrlEncode(string str) {
        string escape = Uri.EscapeUriString(str); 
        return Regex.Replace(escape, "([#;?:@&=+$,])", new MatchEvaluator(EscapeReservedCharacters));
    }

Это может быть по своему решению (придется спросить об этом людей Microsoft) из-за того, что косые черты передаютсяявляются довольно неотъемлемой частью маршрутов.Если это так, я нахожу это немного странным, так как документация для Uri.EscapeUriString() гласит, что это основное использование как:

Используйте метод EscapeUriString, чтобы подготовить неэкранированную строку URI дляпараметр для конструктора Uri.

Следуя коду, который генерирует URL-адрес маршрута, он, похоже, вообще не использует класс Uri - URL создается и возвращается в виде строки.

Если вы передадите его как параметр строки запроса, а не как часть указанного маршрута, он будет правильно закодирован в URL (но, конечно, изменит структуру вашего URL).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...