2010-12-09 3 views
132

Если вы имеете дело только с кодировкой url, я должен использовать EscapeUriString?В чем разница между EscapeUriString и EscapeDataString?

+5

Всегда избегайте каждого отдельного ** значения **, используя `Uri.EscapeDataString()`, как описано в ответе @ Livven. С другими подходами система просто не располагает достаточной информацией для получения ожидаемого результата для каждого возможного ввода. – Timo 2016-06-16 12:34:09

ответ

79

Вы используете EscapeUriString, если вы выбрали URI и EscapeDataString везде.

Существуют различия в том, как эти два кодируют строки.

Больше информации здесь: http://blogs.msdn.com/b/yangxind/archive/2006/11/09/don-t-use-net-system-uri-unescapedatastring-in-url-decoding.aspx

+3

Я не уверен, что ссылка на самом деле предоставляет больше информации, поскольку она касается unescaping, а не esacaping. – Steven 2013-08-30 15:52:07

+1

Это в основном такая же разница. Если вы действительно прочитали статью, есть таблица вокруг середины, которая фактически ускользает (не unescapes), чтобы показать различия (по сравнению с `URLEncode` тоже). – Jcl 2013-08-30 15:57:58

+2

Мне все еще не ясно - что делать, если я не избегаю целого URI, а только его часть (т. Е. Данные * для параметра строки запроса)? Я убегаю данные для URI, или EscapeDataString подразумевает что-то совершенно другое? – BrainSlugs83 2013-11-10 03:37:29

45

плюс (+) символы могут выявить много о разнице между этими методами. В простом URI символ плюса означает «пространство». Рассмотрим запрос Google для "счастливого кота":

https://www.google.com/?q=happy+cat

Это правильный URI (попробуйте), и EscapeUriString не изменит его.

Теперь рассмотрит запрос Google для "счастливых C++":

https://www.google.com/?q=happy+c++

Это правильный URI (попробуйте), но он производит поиск "счастливых с", так как два плюсы интерпретируются как пробелы. Чтобы исправить это, мы можем пройти "счастливый C++" в EscapeDataString и вуаля *:

https://www.google.com/?q=happy+c%2B%2B

*) кодированная строка данных на самом деле «счастливый% 20с% 2B% 2B «; % 20 является шестнадцатеричным для символа пробела, а% 2B - шестнадцатеричным для символа плюса.

Если вы используете UriBuilder, как и должно быть, вам понадобится только EscapeDataString для правильного удаления некоторых компонентов всего вашего URI. @ Ответ Ливенна на этот вопрос еще раз доказывает, что на самом деле нет причин использовать EscapeUriString.

104

Я не нашел существующие ответы удовлетворительными, поэтому я решил немного углубиться, чтобы решить эту проблему. Удивительно, но ответ очень прост:

Нет веской причины когда-либо использовать Uri.EscapeUriString. Если вам нужно преобразовать строку в процентах, всегда используйте Uri.EscapeDataString.

Почему это? Согласно documentation:

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

Это не имеет смысла. По RFC 2396:

URI, всегда находится в «убежал» форму, так как выпадать или неэкранированные завершенное URI может изменить свою семантику.

В то время как цитируемый RFC был устарел RFC 3986, точка все еще стоит. Давайте проверим это, глядя на некоторые конкретные примеры:

  1. У вас есть простой URI, например:

    http://example.org/ 
    

    Uri.EscapeUriString не изменит.

  2. Вы решили вручную отредактировать строку запроса без учета для выхода:

    http://example.org/?key=two words 
    

    Uri.EscapeUriString будет (правильно) бежать пространство для вас:

    http://example.org/?key=two%20words 
    
  3. Вы решили вручную редактировать строка запроса дополнительно:

    http://example.org/?parameter=father&son 
    

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

  4. Вы сами решаете, что вы на самом деле хотите параметр key быть father&son, так что вы исправить предыдущий URL вручную, убегая амперсанд:

    http://example.org/?parameter=father%26son 
    

    Однако Uri.EscapeUriString избежит процента характер тоже, что приводит к двойное кодирование:

    http://example.org/?parameter=father%2526son 
    

Как вы можете видеть, используя Uri.EscapeUriString для предполагаемого цель делает невозможным использование & как часть ключа или значения в строке запроса, а не как разделитель между несколькими парами ключ-значение.

Это связано с тем, что при ошибочной попытке сделать его пригодным для экранирования полных URI он игнорирует зарезервированные символы и пропускает только те символы, которые не являются ни зарезервированными, ни безоговорочными, что, кстати, противоречит documentation. Таким образом, вы не получите что-то вроде http%3A%2F%2Fexample.org%2F, но в итоге вы получите проблемы, проиллюстрированные выше.


В конце концов, если ваш URI действителен, он не должен быть экранированы, чтобы передать в качестве параметра к construtor Ури, и если это не действует, то называя Uri.EscapeUriString не является магическим решением либо , Фактически, он будет работать во многих случаях, если не в большинстве случаев, но он ни в коем случае не является надежным.

Вы всегда должны создавать свои URL-адреса и строки запросов, собирая пары ключ-значение и процентное кодирование, а затем объединяя их с необходимыми разделителями. Вы можете использовать Uri.EscapeDataString для этой цели, но не Uri.EscapeUriString, так как он не избегает зарезервированных символов, как упоминалось выше.

0

Комментарии в source Обратите внимание на разницу четко. Почему эта информация не представлена ​​с помощью комментариев документации XML, для меня загадка.

EscapeUriString:

Этот метод будет экранировать любой символ, который не является зарезервированным или несдержанным характером, в том числе знаков процента. Обратите внимание: EscapeUriString также не будет выходить из знака '#'.

EscapeDataString:

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

Так что разница в том, как они обрабатывают зарезервированы символов. EscapeDataString ускользает от них; EscapeUriString нет.

Согласно RFC, зарезервированным символам: :/?#[]@!$&'()*+,;=

Для полноты незарезервированных символов являются буквенно-цифровыми и -._~

Оба метода избежать символов, которые не являются ни сдержанными, ни безоговорочными.

Я не согласен с общим notion, что EscapeUriString является злым. Я думаю, что метод, который ускользает только незаконным символов (таких как пробелы), а не зарезервировано символов полезно. Но у него есть причуда в том, как он обрабатывает символ %. Проко-кодированные символы (%, за которыми следуют 2 шестнадцатеричных цифры) являются legal в URI. Я думаю, что EscapeUriString было бы гораздо более полезным, если бы он обнаружил этот шаблон и избегал кодирования %, когда он сразу же исходил из двух шестнадцатеричных цифр.

Смежные вопросы