Ответ 1
HttpServerUtility.UrlEncode
будет использовать HttpUtility.UrlEncode
внутренне. Особой разницы нет. Причиной существования Server.UrlEncode
является совместимость с классическим ASP.
Есть ли разница между Server.UrlEncode и HttpUtility.UrlEncode?
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.
Имейте в виду, что вы, вероятно, не должны использовать ни один из этих методов. Microsoft Библиотека скриптов для Anti-Cross Site содержит замены для HttpUtility.UrlEncode
и HttpUtility.HtmlEncode
, которые являются более стандартизованными и более безопасными. В качестве бонуса вы также получаете метод JavaScriptEncode
.
Server.UrlEncode() предназначен для обеспечения обратной совместимости с классическим ASP,
Server.UrlEncode(str);
Является эквивалентным:
HttpUtility.UrlEncode(str, Response.ContentEncoding);
То же самое, Server.UrlEncode()
вызывает HttpUtility.UrlEncode()
Ускоренная перемотка почти через 9 лет с тех пор, как это было впервые задано, и в мире .NET Core и .NET Standard кажется, что наиболее распространенными параметрами для URL-кодирования являются WebUtility.UrlEncode (под System.Net
) и Uri.EscapeDataString. Судя по самому популярному ответу здесь и в других местах, предпочтительнее Uri.EscapeDataString. Но так ли? Я сделал некоторый анализ, чтобы понять различия, и вот что я придумал:
WebUtility.UrlEncode
кодирует пространство как +
; Uri.EscapeDataString
кодирует его как %20
.Uri.EscapeDataString
percent-encodes !
, (
, )
и *
; WebUtility.UrlEncode
нет.WebUtility.UrlEncode
percent-encodes ~
; Uri.EscapeDataString
нет.Uri.EscapeDataString
выдает a UriFormatException
для строк длиной более 65520 символов; WebUtility.UrlEncode
нет. (Более распространенная проблема, чем вы могли бы подумать, особенно при работе с данными формы с кодировкой URL.)Uri.EscapeDataString
выдает a UriFormatException
в высоких суррогатных персонажах; WebUtility.UrlEncode
нет. (Это UTF-16, вероятно, намного реже.)В целях кодирования URL символы вписываются в одну из трех категорий: безоговорочно (легально по URL-адресу); зарезервировано (легально, но имеет особое значение, поэтому вы можете его закодировать); и все остальное (всегда должно быть закодировано).
В соответствии с RFC зарезервированные символы: :/?#[]@!$&'()*+,;=
И незарезервированные символы являются буквенно-цифровыми и -._~
Uri.EscapeDataString четко определяет свою миссию:% -encode все зарезервированные и незаконные символы. WebUtility.UrlEncode более двусмысленна как в определении, так и в реализации. Как ни странно, он кодирует некоторые зарезервированные символы, но не другие (почему круглые скобки, а не скобки?), А незнакомец все еще кодирует тот невинно безоговорочный символ ~
.
Поэтому я согласен с популярным советом - используйте Uri.EscapeDataString, когда это возможно, и поймите, что зарезервированные символы, такие как /
и ?
, будут закодированы. Если вам нужно иметь дело с потенциально большими строками, особенно с содержимым формы с кодировкой URL-адреса, вам нужно либо вернуться на WebUtility.UrlEncode, либо принять его причуды, либо иначе обойти проблему.
Здесь код, который я использовал, чтобы определить, какие символы кодируются по-разному:
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}");