Відповіді:
HttpServerUtility.UrlEncode
буде використовувати HttpUtility.UrlEncode
внутрішньо. Конкретної різниці немає. Причиною існування Server.UrlEncode
є сумісність із класичним ASP.
Раніше у мене були сильні головні болі з цими методами, я рекомендую вам уникати будь-яких варіантів UrlEncode
, а замість цього використовуватиUri.EscapeDataString
- принаймні, що людина має зрозумілу поведінку.
Подивимось ...
HttpUtility.UrlEncode(" ") == "+" //breaks ASP.NET when used in paths, non-
//standard, undocumented.
Uri.EscapeUriString("a?b=e") == "a?b=e" // makes sense, but rarely what you
// want, since you still need to
// escape special characters yourself
Але моїм особистим фаворитом має стати HttpUtility.UrlPathEncode - ця річ справді незрозуміла. Він кодує:
У ньому також є кохана специфічна документація MSDN "Кодує частину шляху URL-рядка для надійної передачі HTTP від веб-сервера до клієнта." - не пояснюючи насправді, що робить. Ви рідше стріляєте собі в ногу узі ...
Словом, дотримуйтесь Uri.EscapeDataString .
?
і хто може сказати, що потрібно закодувати, а які - роздільники? Щодо простору: в обох випадках простір знаходиться у хеші, тому наявність або відсутність запиту-фрагмента не має значення. І нарешті, недоцільно псувати Uri, як у другому прикладі, що містить%. UrlPathEncode
Метод рівнини BORKED і ніколи не повинен використовуватися.
Перемотування вперед майже 9 років з моменту вперше запиту, і у світі .NET Core та .NET Standard, здається, найбільш поширеними у нас варіантами кодування URL є WebUtility.UrlEncode (під System.Net
) та Uri.EscapeDataString . Судячи з найпопулярнішої відповіді тут і деінде, Uri.EscapeDataString видається кращим. Але це? Я зробив аналіз, щоб зрозуміти відмінності, і ось що я придумав:
WebUtility.UrlEncode
кодує простір як +
; Uri.EscapeDataString
кодує його як %20
.Uri.EscapeDataString
відсотки кодують !
, (
, )
, і *
; WebUtility.UrlEncode
не.WebUtility.UrlEncode
відсотки-кодує ~
; Uri.EscapeDataString
не.Uri.EscapeDataString
кидає UriFormatException
на струнах довжиною більше 65 520 символів; WebUtility.UrlEncode
не. ( Більш поширена проблема, ніж ви можете подумати, особливо при роботі з кодованими URL-адресами даними форми .)Uri.EscapeDataString
кидає UriFormatException
на високих сурогатних персонажів ; WebUtility.UrlEncode
не. (Це UTF-16, мабуть, набагато рідше.)Для цілей кодування URL-адреси символи вписуються в одну з 3 категорій: незарезервована (юридична в URL-адресі); зарезервований (юридичний в Росії, але має особливе значення, так що ви , можливо , захочете кодувати його); і все інше (завжди має бути закодовано).
За даними RFC , зарезервовані символи::/?#[]@!$&'()*+,;=
А незарезервовані символи буквено-цифрові та -._~
Uri.EscapeDataString чітко визначає свою місію:% -кодує всі зарезервовані та незаконні символи. WebUtility.UrlEncode є більш неоднозначним як у визначенні, так і в реалізації. Як не дивно, він кодує деякі зарезервовані символи, але не інші (чому круглі дужки, а не дужки ??), а незнайомець все ж кодує цей безнезахисний ~
символ.
Тому я погоджуюся з популярною порадою - використовуйте Uri.EscapeDataString, коли це можливо, і розумію, що зарезервовані символи люблять /
і ?
будуть закодовані. Якщо вам потрібно мати справу з потенційно великими рядками, особливо з вмістом форми, що кодується URL-адресою, вам потрібно буде або перейти назад на WebUtility.UrlEncode і прийняти його химерності , або іншим чином вирішити проблему.
EDIT: Я намагався виправити все з примх , згаданих вище в Flurl через Url.Encode
, Url.EncodeIllegalCharacters
і Url.Decode
статичні методи. Вони знаходяться в основному пакеті (який крихітний і не містить усіх HTTP-матеріалів), або ви можете вирвати їх з джерела. Я вітаю будь-які коментарі / відгуки щодо них.
Ось код, який я використав, щоб виявити, які символи кодуються по-різному:
var diffs =
from i in Enumerable.Range(0, char.MaxValue + 1)
let c = (char)i
where !char.IsHighSurrogate(c)
let diff = new {
Original = c,
UrlEncode = WebUtility.UrlEncode(c.ToString()),
EscapeDataString = Uri.EscapeDataString(c.ToString()),
}
where diff.UrlEncode != diff.EscapeDataString
select diff;
foreach (var diff in diffs)
Console.WriteLine($"{diff.Original}\t{diff.UrlEncode}\t{diff.EscapeDataString}");
Майте на увазі, що ви, мабуть, не повинні використовувати жоден із цих методів. Від Microsoft Anti-Cross Site Scripting Library включає в себе заміну для HttpUtility.UrlEncode
і HttpUtility.HtmlEncode
що обидва є більш відповідними стандартами, і більш безпечним. Як бонус, ви також отримуєте JavaScriptEncode
метод.