.Net Uri Encoding RFC 2396 против RFC 3986

Во-первых, немного предыстории ... В рамках интеграции со сторонним поставщиком у меня есть веб-приложение C # .Net, которое получает URL-адрес с кучей информации в строке запроса. Этот URL-адрес подписан хешем MD5 и общим секретным ключом. По сути, я втягиваю строку запроса, удаляю их хеш, выполняю свой собственный хеш для оставшейся строки запроса и проверяю, совпадает ли мой с той, которая была предоставлена.

Я получаю Ури следующим образом ...

Uri uriFromVendor = new Uri(Request.Url.ToString());
string queryFromVendor = uriFromVendor.Query.Substring(1); //Substring to remove question mark

Моя проблема возникает из-за строк запроса, содержащих специальные символы, такие как умляут (ü). Поставщик вычисляет свой хэш на основе представления RFC 2396, равного %FC. Мое приложение C # .Net вычисляет свой хэш на основе представления RFC 3986, равного %C3%BC. Излишне говорить, что наши хэши не совпадают, и я выкидываю свои ошибки.

Как ни странно, в документации для класса Uri в .Net говорится, что он должен соответствовать RFC 2396, если иное не установлено в RFC 3986, но у меня нет записи в моем web.config файле, которая, по их словам, необходима для такого поведения.

Как я могу заставить конструктор Uri использовать соглашение RFC 2396?

В противном случае существует ли простой способ преобразовать пары октетов RFC 3986 в октеты RFC 2396?


person Colin    schedule 11.08.2011    source источник
comment
Ничего общего с вашим вопросом, но зачем вы здесь создаете новый Uri? Вы можете просто сделать string queryFromVendor = Request.Url.Query.Substring(1);   -  person magnattic    schedule 12.08.2011
comment
Какую версию .NET вы используете?   -  person John Saunders    schedule 12.08.2011
comment
Я использую .Net 4.0. Также, что любопытно, когда я пытался использовать Request.Url.Query, умлаут проходил как %ufffd, что является символом �.   -  person Colin    schedule 12.08.2011


Ответы (3)


Ничего общего с вашим вопросом, но зачем вы здесь создаете новый Uri? Вы можете просто сделать string queryFromVendor = Request.Url.Query.Substring(1); - аттики

+1 за аттики! Я вернулся, чтобы попытаться удалить посторонний Uri, который я создавал, и внезапно в строке появился умляут, закодированный как UTF-8 вместо UTF-16.

Сначала я не думал, что это сработает. Где-то в этой строке я пытался получить URL-адрес с помощью Request.QueryString, но из-за этого умлаут проходил как %ufffd, который является символом �. В интересах свежего взгляда я попробовал предложение atticae, и оно сработало.

Я почти уверен, что ответ связан с кое-что прочитал здесь.

C # использует UTF-16 во всех своих строках с инструментами для кодирования, когда дело доходит до работы с потоками и файлами, которые приводят нас к ...

ASP.NET по умолчанию использует UTF-8, и трудно вспомнить время, когда это не лучший выбор ...

Мои проблемы возникли отсюда ...

Uri uriFromVendor = new Uri(Request.Url.ToString());

Взяв Request.Url uri и создав другой uri, он кодировал как стандарт C # UTF-16. Используя исходный uri, он остался в стандарте .Net UTF-8.

Спасибо всем за помощь.

person Colin    schedule 12.08.2011

Мне интересно, не отвлекает ли это внимание:

Я говорю это, потому что FC - это UTF16-представление u с умлаутом; C2BC - это представление UTF8.

Интересно, может ли помочь один из методов System.Text.Encoding для преобразования исходных данных в обычную строку .Net.

Этот вопрос тоже может представлять интерес: Кодирование и декодирование URL-адресов rfc2396

person Russ Clarke    schedule 12.08.2011

Я не знаю о стандартной кодировке для конструкторов Uri, но если все остальное не удается, вы всегда можете самостоятельно декодировать URL-адрес и закодировать его в любой кодировке, которая вам нравится.

HttpUtility-Class имеет методы UrlDecode() и UrlEncode(), которые позволяют указать System.Text.Encoding в качестве второго параметра.

Например:

string decodedQueryString = HttpUtility.UrlDecode(Request.Url.Query.Substring(1));
string encodedQueryString = HttpUtility.UrlEncode(decodedQueryString, System.Text.Encoding.GetEncoding("utf-16"));
// calc hash here
person magnattic    schedule 12.08.2011
comment
Похоже, метод UrlEncode немного переусердствует. вывод закодировал все в строке ... c% 00o% 00n% 00f% 00i% 00r% 00m% 00a% 00t% 00i% 00o% 00 ... - person Colin; 12.08.2011
comment
Примечание: все же удалось преобразовать умлаут обратно в %FC. Есть ли способ быть более избирательным, чтобы он не кодировал амперсанды, плюсы и% 00? - person Colin; 12.08.2011
comment
Хорошо, прежде всего: результат% 00 является результатом кодировки utf-16, которую я использовал здесь в качестве примера. Замените его на любую желаемую кодировку. Если вы хотите преобразовать ü в% FC, возможно, вы ищете latin1: System.Text.Encoding.GetEncoding("latin1") - person magnattic; 13.08.2011
comment
Теперь ваша проблема, похоже, решена, просто для полноты: вы можете обойти кодирование символов & и =, разделив строку запроса, кодируя каждую часть и собирая ее обратно. Но, как я уже сказал, весь ответ - всего лишь обходной путь к проблеме. - person magnattic; 13.08.2011