Ответы:
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
метод прост и не должен использоваться.
Перенесемся вперед почти 9 лет с тех пор, как это было впервые задано, и в мире .NET Core и .NET Standard наиболее распространенными вариантами кодирования URL, по- видимому, являются WebUtility.UrlEncode (under 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); зарезервировано (законно, но имеет особое значение, так что вы можете закодировать его); и все остальное (всегда должно быть закодировано).
По данным РФЦ , зарезервированные символы::/?#[]@!$&'()*+,;=
И незарезервированные символы являются буквенно-цифровыми и -._~
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
метод.