IIS выполняет незаконную замену символов? Если так, как это остановить? - PullRequest
44 голосов
/ 27 октября 2011

Контекст: ASP.NET MVC, работающий в IIS, с URL-кодом в кодировке UTF-8%.

Использование стандартного шаблона проекта и тестового действия в HomeController, например:

public ActionResult Test(string id)
{
    return Content(id, "text/plain");
}

Это прекрасно работает для большинства% UTF-8-кодированных маршрутов, таких как:

http://mydevserver/Home/Test/%e4%ba%ac%e9%83%bd%e5%bc%81

с ожидаемым результатом 京都 101

Однако при использовании маршрута:

http://mydevserver/Home/Test/%ee%93%bb

URL-адрес не получен правильно.

В стороне: %ee%93%bb - кодированная точка% -x 0xE4FB;базовая многоязычная плоскость, зона частного пользования;но в конечном итоге - действительный код Unicode;Вы можете проверить это вручную или с помощью:

string value = ((char) 0xE4FB).ToString();
string encoded = HttpUtility.UrlEncode(value); // %ee%93%bb

Теперь, что будет дальше, зависит от веб-сервера;на сервере разработки Visual Studio (aka cassini) получено правильное id - строка длиной один, содержащая кодовую точку 0xE4FB.

Если, однако, я делаю это в IIS или IIS Express,Я получаю другой id, в частности "î“»", кодовые точки: 0xEE, 0x201C, 0xBB.Вы сразу узнаете первое и последнее как начало и конец нашей строки, закодированной в процентах ... так что же произошло в середине?

Ну:

Это выглядит мне оченьТак же, как IIS выполнил некий перевод цитат при обработке моего URL.Теперь, возможно, это может быть использовано в нескольких сценариях (я не знаю), но это, конечно, плохо, когда это происходит в середине блока, кодированного% UTF-8.

Обратите внимание, что HttpContext.Current.Request.Raw также показывает, что этот перевод произошел, так что это не похоже на ошибку MVC;обратите внимание также на комментарий Дарина, подчеркивающий, что он работает по-разному в части пути к URL-адресу запроса.

Итак (с двумя разделителями):

  1. - в моем анализе отсутствуют некоторые важные тонкостиЮникод / ​​обработка URL?
  2. как мне это исправить?(т.е. сделать так, чтобы я получил ожидаемый символ)

Ответы [ 3 ]

9 голосов
/ 27 октября 2011
id = Encoding.UTF8.GetString(Encoding.Default.GetBytes(id));

Это даст вам ваш оригинальный идентификатор. IIS использует кодировку по умолчанию (ANSI) для символов пути. Ваша строка, закодированная в URL, декодируется с использованием этого, и поэтому вы получаете странную вещь назад.

Чтобы получить исходный идентификатор, вы можете преобразовать его обратно в байты и получить строку, используя кодировку utf8.

См. Юникод и фильтры ISAPI

ISAPI Filter - это ANSI API - все значения вы можете получить / установить с помощью API должен быть ANSI. Да, я знаю, что это шокирует; в конце концов, это 2006 и все в настоящее время в Unicode ... но помните, что этот API возникла более десяти лет назад, когда почти ничего не было 32-битным меньше Unicode. Кроме того, помните, что протокол HTTP, который ISAPI напрямую манипулирует в ANSI, а не в Unicode.

РЕДАКТИРОВАТЬ: Поскольку вы упомянули, что он работает с большинством других символов, поэтому я предполагаю, что IIS имеет какой-то механизм обнаружения кодирования, который в этом случае не работает. В качестве обходного пути вы можете использовать префикс вашего идентификатора с этим символом, а затем легко определить, возникла ли проблема (если этот символ отсутствует). Не очень идеальное решение, но оно будет работать. Затем вы можете написать свой собственный механизм связывания модели и класс-оболочку в ASP.NET MVC, чтобы сделать ваш код потребления более чистым.

1 голос
/ 14 октября 2014

В конечном счете, чтобы обойти это, мне пришлось использовать request.ServerVariables["HTTP_URL"] и некоторый ручной анализ с кучей откатов обработки ошибок (дополнительно компенсируя некоторые связанные с этим ошибки в Uri). Не очень, но влияет только на небольшое количество неловких запросов.

1 голос
/ 27 октября 2011

Когда-то сами URL не были в UTF-8.Они были в кодовой странице ANSI.Это облегчает тот факт, что они часто используются для выбора путей в файловой системе сервера.В древние времена у IE была возможность указать, хотите ли вы отправлять URL-адреса UTF-8 или нет.

Возможно, в недрах конфигурации IIS есть место для указания кодировки URL, и, возможно, нет.

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