Respostas:
HttpServerUtility.UrlEncode
usará HttpUtility.UrlEncode
internamente. Não há diferença específica. A razão da existência de Server.UrlEncode
é compatibilidade com o ASP clássico.
Eu tive dores de cabeça significativas com esses métodos antes, eu recomendo que você evite qualquer variante UrlEncode
e useUri.EscapeDataString
- pelo menos esse tenha um comportamento compreensível.
Vamos ver...
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
Mas meu favorito pessoal deve ser o HttpUtility.UrlPathEncode - isso é realmente incompreensível. Codifica:
Ele também possui a documentação específica do MSDN, "Codifica a parte do caminho de uma string de URL para uma transmissão HTTP confiável do servidor da Web para um cliente". - sem realmente explicar o que faz. É menos provável que você atinja seu pé com uma Uzi ...
Em suma, atenha-se ao Uri.EscapeDataString .
?
e quem pode dizer quais devem ser codificados e quais servem como separadores? Quanto ao espaço: nos dois casos, o espaço está no hash; portanto, a presença ou ausência de um fragmento de consulta não deve importar. E, finalmente, é indesculpável corromper um Uri, como no segundo exemplo, contendo um%. O UrlPathEncode
método é simples e nunca deve ser usado.
Avançando quase 9 anos desde que isso foi solicitado pela primeira vez, e no mundo do .NET Core e .NET Standard, parece que as opções mais comuns que temos para codificação de URL são WebUtility.UrlEncode (under System.Net
) e Uri.EscapeDataString . A julgar pela resposta mais popular aqui e em outros lugares, Uri.EscapeDataString parece ser preferível. Mas é isso? Eu fiz algumas análises para entender as diferenças e aqui está o que eu vim com:
WebUtility.UrlEncode
codifica o espaço como +
; Uri.EscapeDataString
codifica como %20
.Uri.EscapeDataString
por cento codifica !
, (
, )
, e *
; WebUtility.UrlEncode
não.WebUtility.UrlEncode
codificação por cento ~
; Uri.EscapeDataString
não.Uri.EscapeDataString
lança um UriFormatException
em seqüências de caracteres com mais de 65.520 caracteres; WebUtility.UrlEncode
não. ( Um problema mais comum do que você imagina, principalmente ao lidar com dados de formulário codificados por URL .)Uri.EscapeDataString
joga um UriFormatException
sobre os personagens substitutos altos ; WebUtility.UrlEncode
não. (Isso é uma coisa UTF-16, provavelmente muito menos comum.)Para fins de codificação de URL, os caracteres se enquadram em uma de três categorias: sem reserva (legal em uma URL); reservado (legal, mas tem um significado especial, então você pode querer codificá-lo); e tudo o mais (sempre deve ser codificado).
De acordo com a RFC , os caracteres reservados são::/?#[]@!$&'()*+,;=
E os caracteres não reservados são alfanuméricos e -._~
Uri.EscapeDataString define claramente sua missão:%-codode todos os caracteres reservados e ilegais. WebUtility.UrlEncode é mais ambíguo na definição e na implementação. Estranhamente, ele codifica alguns caracteres reservados, mas não outros (por que parênteses e não parênteses?), E, ainda mais estranho, codifica esse ~
personagem inocentemente não reservado .
Portanto, concordo com o conselho popular - use Uri.EscapeDataString quando possível e entenda que caracteres reservados gostam /
e ?
serão codificados. Se você precisar lidar com cadeias potencialmente grandes, principalmente com conteúdo de formulário codificado por URL, precisará usar o WebUtility.UrlEncode e aceitar suas peculiaridades ou solucionar o problema.
EDIT: Eu tenho tentado retificar TODAS as peculiaridades mencionados acima em Flurl via Url.Encode
, Url.EncodeIllegalCharacters
e Url.Decode
métodos estáticos. Eles estão no pacote principal (que é pequeno e não inclui todo o material HTTP), ou fique à vontade para extraí-los da fonte. Congratulo-me com quaisquer comentários / feedback que você tem sobre estes.
Aqui está o código que eu usei para descobrir quais caracteres são codificados de maneira diferente:
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}");
Lembre-se de que você provavelmente não deveria estar usando nenhum desses métodos. A Biblioteca de scripts anti-site da Microsoft inclui substituições HttpUtility.UrlEncode
e HttpUtility.HtmlEncode
que são mais compatíveis com os padrões e mais seguras. Como bônus, você recebe um JavaScriptEncode
método também.