Server.UrlEncode против HttpUtility.UrlEncode - PullRequest
169 голосов
/ 02 марта 2009

Есть ли разница между Server.UrlEncode и HttpUtility.UrlEncode?

Ответы [ 6 ]

251 голосов
/ 18 июля 2009

У меня были значительные головные боли с этими методами раньше, Я рекомендую вам избегать любого варианта 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 - эта вещь действительно непостижима. Кодирует:

  • "" ==> "% 20"
  • "100% true" ==> "100 %% 20true" (хорошо, ваш URL сейчас не работает)
  • "test A.aspx # anchor B" ==> "test% 20A.aspx # anchor% 20B "
  • "test A.aspx? Hmm # anchor B" ==> "test% 20A.aspx? Hmm # anchor B " ( обратите внимание на разницу с предыдущей escape-последовательностью! )

Он также имеет прекрасную документацию MSDN «Кодирует часть пути строки URL для надежной передачи HTTP с веб-сервера клиенту». - фактически не объясняя, что он делает. У вас меньше шансов выстрелить себе в ногу из узи ...

Короче, придерживайтесь Uri.EscapeDataString .

130 голосов
/ 02 марта 2009

HttpServerUtility.UrlEncode будет использовать HttpUtility.UrlEncode внутри. Особой разницы нет. Причиной существования Server.UrlEncode является совместимость с классическим ASP.

41 голосов
/ 19 декабря 2017

Быстрая перемотка почти 9 лет с тех пор, как это было впервые задано, и в мире .NET Core и .NET Standard наиболее распространенными вариантами кодирования URL, по-видимому, являются WebUtility.UrlEncode (под System.Net) и Uri.EscapeDataString . Судя по наиболее популярному ответу здесь и в других местах, Uri.EscapeDataString представляется предпочтительным. Но так ли это? Я сделал некоторый анализ, чтобы понять различия, и вот что я придумал:

В целях кодирования URL символы попадают в одну из 3 категорий: безрезультатно (допустимо в URL); зарезервировано (допустимо, но имеет особое значение, поэтому вы могли бы захотеть закодировать его); и все остальное (всегда должно быть закодировано).

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

И незарезервированные символы алфавитно-цифровые и -._~

Вердикт

Uri.EscapeDataString четко определяет свою миссию:% -кодировать все зарезервированные и недопустимые символы. WebUtility.UrlEncode более неоднозначен как в определении, так и в реализации. Как ни странно, он кодирует некоторые зарезервированные символы, но не другие (почему скобки, а не скобки ??), и, что еще более странно, он кодирует этот невинно незарезервированный ~ символ.

Поэтому я согласен с популярным советом - используйте Uri.EscapeDataString , когда это возможно, и понимайте, что зарезервированные символы, такие как / и ?, будут закодированы. Если вам нужно иметь дело с потенциально большими строками, особенно с содержимым формы в кодировке URL, вам нужно либо воспользоваться WebUtility.UrlEncode и принять его причуды, либо иным образом обойти проблему.


РЕДАКТИРОВАТЬ: Я попытался исправить ВСЕ причуды, упомянутые выше в 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}");
10 голосов
/ 02 марта 2009

Server.UrlEncode () предназначен для обеспечения обратной совместимости с Classic ASP,

Server.UrlEncode(str);

Эквивалентно:

HttpUtility.UrlEncode(str, Response.ContentEncoding);
4 голосов
/ 02 марта 2009

То же самое, Server.UrlEncode() звонки HttpUtility.UrlEncode()

...