HttpUtility.ParseQueryString() всегда кодирует специальные символы в unicode

При использовании HttpUtility из System.Web я обнаруживаю, что каждый раз, когда я вызываю метод .ParseQueryString, у меня есть специальные символы, кодирующие их эквивалентные представления в Юникоде. Я пробовал со многими различными типами кодирования, и все, кажется, дают тот же результат. Пример моего кода:

string text = "ich möchte diese Bild für andere freigeben"
var urlBuilder = new UriBuilder(url);
var query = HttpUtility.ParseQueryString(urlBuilder.Query, Encoding.UTF8);
query["text"] = text;    
urlBuilder.Query = query.ToString();
string finalUrl = urlBuilder.ToString();

И строка в finalUrl, которую я получил бы от этого, будет:

текст = Ich + т% u00f6chte + Diese + Bild + ж% u00fcr + Andere + freigeben

Я попытался использовать Encoding.UTF8, Encoding.ASCII и Encoding.Default, и все они дают одинаковый результат. Что я могу сделать, чтобы достичь желаемого формата UrlEncoding:

текст = Ich %20m% C3% B6chte %20diese %20Bild %20f% C3% BCr %20andere %20freigeben

Как всегда, заблаговременно за помощь/совет!

Ответ 1

Проблема заключается в следующем:

urlBuilder.Query = query.ToString();

HttpUtility.ParseQueryString возвращает NameValueCollection, но на самом деле является внутренним классом, который называется HttpValueCollection. Этот класс имеет переопределение метода ToString(). Он генерирует закодированную строку запроса, но для ее кодировки URL он использует HttpUtility.UrlEncodeUnicode (tinyurl.com/HttpValue). Это приводит к значениям% uXXXX.

Если вам нужен другой тип кодировки URL, вы можете избежать HttpUtility.ParseQueryString или декодировать результат ToString() и затем закодировать его:

urlBuilder.Query = Uri.EscapeUriString(HttpUtility.UrlDecode(query.ToString()));

Ответ 2

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

Исправление довольно просто, в web.config просто добавьте следующий параметр (протестирован и работает в .NET 4.5):

<appSettings>
  <add key="aspnet:DontUsePercentUUrlEncoding" value="true" />
</appSettings>

Установка этого значения в значение true определяет, как .NET будет кодировать определенные символы в URL-адресе. В частности, такие символы, как ä, ë, ö и т.д. Я думаю, это может быть потому, что есть несколько способов кодирования этих символов. Как это обычно делается с префиксом %C3, который означает, что следующий символ имеет умляут (я уверен, что он работает).

Способ HttpUtility.ParseQueryString по умолчанию отличается. Он кодирует символ в фактический процентный кодированный символ Юникода %u00f6. Это может вызвать некоторые проблемы, поскольку это не значение по умолчанию даже внутри самой .NET, HttpUtility.UrlEncode, например, будет кодировать его до %C3%B6. Изменение вышеуказанного параметра гарантирует, что оба метода возвращают похожие результаты.

Ответ 3

Я не знаком с ParseQueryString, но из документации вы можете преобразовать правильно отформатированный запрос в пары значений имени. Из вашего сообщения кажется, что вы пытаетесь сделать обратное: преобразовать пары данных в правильно отформатированный запрос. Вместо этого вы можете попробовать использовать HttpUtility.UrlEncode

string text = "ich möchte diese Bild für andere freigeben"
var urlBuilder = new UriBuilder(url);
String query = "text=" + HttpUtility.UrlEncode(text);  
urlBuilder.Query = query;
string finalUrl = urlBuilder.ToString();

Ответ 4

Использование: System.Web.HttpUtility.ParseQueryString(Request.Url.Query, UTF8Encoding.Default)

Например: www.mydomain.com/page?name=Jia+Almi%F1a&PAYID=123456&TOWN=LONDON

Фактическое имя: Jia Almiña

Request.Querystring ["name"]: Jia Almi a (это не правильно)

Сначала получите необработанный URL, который будет Request.Url.Query:? Name = Jia + Almi% F1a & PAID = 123456 & TOWN = LONDON

System.Web.HttpUtility.ParseQueryString(Request.Url.Query, UTF8Encoding.Default).Get("имя") будет Джия Алминья