Я разыскивал ошибку на приложении Перезаписи URL. Ошибка обнаружилась как проблема кодирования на некоторых диакритических символах в querystring.
В основном проблема состояла в том, что запрос, который был в основном/search.aspx? search=heřmánek становился переписанным с querystring "search=he%c5%99m%c3%a1nek"
Правильное значение (использующий некоторый другой, рабочий код) было переписыванием querystring как "search=he%u0159m%u00e1nek"
Отметьте различие между двумя строками. Однако, если Вы отправляете обоих, которые Вы будете видеть, что Кодирование URL воспроизводит ту же строку. Это - только когда Вы используете контекст. Перепишите функцию, кодирование повреждается. Поврежденная строка возвращает 'heÅmánek' (использующий Запрос. QueryString ["Поиск"] и рабочая строка возвращает 'heřmánek'. Это изменение происходит после вызова с переписать функцией.
Я проследил это вниз до одного набора кода с помощью Запроса. QueryString (работа) и другой Запрос использования. URL. Запрос (запрос. URL возвращает экземпляр Uri).
В то время как я разработал ошибку существует дыра в моем понимании здесь, поэтому если кто-либо знает различие, я готов к уроку.
Ваш вопрос действительно вызвал у меня интерес, поэтому я немного почитал за последний час или около того. Я не совсем уверен, что нашел ответ, но я брошу его там, чтобы узнать, что вы думаете.
Из того, что я читал до сих пор, Request.QueryString на самом деле является «проанализированной версией переменной QUERY_STRING в коллекции ServerVariables» [ссылка] , где как Request.Url (как вы заявили ) необработанный URL-адрес, инкапсулированный в объекте Uri. Согласно этой статье , конструктор класса Uri «... анализирует [строку url], переводит ее в канонический формат и выполняет все необходимые escape-кодировки».
Таким образом, похоже, что Request.QueryString использует другую функцию для анализа переменной QUERY_STRING из конструктора ServerVariables. Это объясняет, почему вы видите разницу между ними. Теперь, почему различные методы кодирования используются пользовательской функцией синтаксического анализа и функцией синтаксического анализа объекта Uri, я полностью не понимаю. Может быть, кто-нибудь немного более разбирающийся в DLL aspnet_isapi сможет ответить на этот вопрос.
В любом случае, надеюсь, мой пост имеет смысл. В качестве побочного примечания я хотел бы добавить еще одну ссылку, которая также предоставила очень подробное и интересное чтение: http://download.microsoft.com/download/6/c/a/6ca715c5-2095-4eec -a56f-a5ee904a1387 / Ch-12_HTTP_Request_Context.pdf
То, что вы указали как "сломанную" кодированную строку, на самом деле является правильной кодировкой в соответствии со стандартами. Та, которую вы указали как "правильную" кодировку, использует нестандартное расширение спецификации, позволяющее формат %uXXXX
(я полагаю, что это должно указывать на кодировку UTF-16).
В любом случае, "сломанная" кодированная строка в порядке. Вы можете использовать следующий код, чтобы проверить это:
Uri uri = new Uri("http://www.example.com/test.aspx?search=heřmánek");
Console.WriteLine(uri.Query);
Console.WriteLine(HttpUtility.UrlDecode(uri.Query));
Работает нормально. Однако... по наитию, я попробовал UrlDecode с указанной кодовой страницей Latin-1 вместо UTF-8 по умолчанию:
Console.WriteLine(HttpUtility.UrlDecode(uri.Query,
Encoding.GetEncoding("iso-8859-1")));
... и получил плохое значение, указанное вами, 'heÅmánek'. Другими словами, похоже, что вызов HttpContext.RewritePath()
каким-то образом изменяет кодирование/декодирование url, чтобы использовать кодовую страницу Latin-1, а не UTF-8, которая является кодировкой по умолчанию, используемой методами UrlEncode/Decode.
Это похоже на ошибку, если вы спросите меня. Вы можете посмотреть на код RewritePath()
в reflector и увидеть, что он определенно играет со строкой запроса - передает ее всем видам виртуальных функций пути и неуправляемому коду IIS.
Интересно, может быть, где-то на этом пути Uri, лежащий в основе объекта Request, манипулируется с неправильной кодовой страницей? Это объясняет, почему Request.Querystring
(который является просто необработанными значениями из HTTP-заголовков) будет правильным, а Uri, использующий неправильную кодировку для диакритических знаков, будет неправильным.