Server.UrlEncode vs HttpUtility.UrlEncode
Pergunta
Existe uma diferença entre Server.UrlEncode e HttpUtility.UrlEncode?
Solução
HttpServerUtility.UrlEncode
usará HttpUtility.UrlEncode
internamente. Não há nenhuma diferença específica. A razão para a existência de Server.UrlEncode
é a compatibilidade com o ASP clássico.
Outras dicas
Eu tinha dores de cabeça significativas com esses métodos antes, eu recomendo que você evitar qualquer variante de UrlEncode
, e em vez disso usar Uri.EscapeDataString
-., pelo menos, que tem 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 o meu favorito tem que ser HttpUtility.UrlPathEncode - essa coisa é realmente incompreensível. Ele codifica:
- "" ==> "% 20"
- "100% verdade" ==> "100 %% 20true" (ok, o seu url está quebrado agora)
- "teste A.aspx # âncora B" ==> "test% 20A.aspx # âncora% 20B "
- "teste A.aspx? Hmm # âncora B" ==> "test% 20A.aspx? Hmm #anchor B " ( notar a diferença com a seqüência de escape anterior )
Ele também tem a específica lovelily documentação MSDN "codifica a parte do caminho de uma seqüência de URL para transmissão HTTP confiável do servidor Web para um cliente." - sem realmente explicar o que ele faz. Que são menos propensos a atirar no próprio pé com uma Uzi ...
Em suma, vara de Uri.EscapeDataString .
Fast-forward quase 9 anos desde que este foi perguntado em primeiro lugar, e no mundo de .NET Core e .NET Padrão, parece que as opções mais comuns que temos para URL-encoding são WebUtility.UrlEncode (sob System.Net
) e Uri.EscapeDataString . A julgar pela resposta mais popular aqui e em outros lugares, Uri.EscapeDataString parece ser preferível. Mas é ele? Eu fiz algumas análises para entender as diferenças e aqui está o que eu vim com:
-
WebUtility.UrlEncode
codifica espaço como+
;Uri.EscapeDataString
codifica como%20
. -
Uri.EscapeDataString
cento codifica!
,(
,)
e*
;WebUtility.UrlEncode
não. -
WebUtility.UrlEncode
cento codifica~
;Uri.EscapeDataString
não. -
Uri.EscapeDataString
lança umaUriFormatException
em cordas com mais de 65,520 caracteres;WebUtility.UrlEncode
não. ( Um problema mais comum do que se poderia pensar, especialmente quando se trata de URL-codificado dados do formulário .) -
Uri.EscapeDataString
lança umaUriFormatException
na caracteres substituto alto ;WebUtility.UrlEncode
não. (Isso é uma coisa UTF-16, provavelmente muito menos comum).
Para fins de codificação de URL, os personagens se encaixam em uma das 3 categorias: sem reservas (legal em uma URL); reservados (legal em, mas tem um significado especial, para que pode quiser codificá-lo); e tudo o mais (deve sempre ser codificado).
De acordo com a RFC , os caracteres reservados são: :/?#[]@!$&'()*+,;=
E os personagens não reservadas são alfanuméricos e -._~
O Veredicto
Uri.EscapeDataString define claramente a sua missão:% -encode todos os caracteres reservados e ilegais. WebUtility.UrlEncode é mais ambígua, tanto definição e implementação. Estranhamente, ele codifica alguns caracteres reservados, mas não outros (por parênteses e não colchetes ??), e mais estranho ainda que codifica esse personagem ~
inocentemente sem reservas.
Por isso, concordo com os conselhos populares - use Uri.EscapeDataString quando possível, e entender que caracteres reservados como /
e ?
vai ficar codificado. Se você precisa lidar com potencialmente grandes cordas, particularmente com conteúdo formulário de URL-codificado, você precisa se quer de volta queda em WebUtility.UrlEncode e aceitar suas peculiaridades, ou de outra forma contornar o problema.
EDIT: Eu href="https://github.com/tmenier/Flurl/issues/262" tentou para corrigir ALL das peculiaridades mencionados acima em Flurl via os métodos Url.Encode
, Url.EncodeIllegalCharacters
, e Url.Decode
estáticos. Estes são na pacote núcleo (que é pequena e não inclui todo o material HTTP), ou sentir-se livre para rasgá-los a partir da fonte. Congratulo-me com qualquer comentários / feedback que você tem sobre estes.
Aqui está o código que usei para descobrir quais os caracteres são codificados de forma 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}");
Tenha em mente que você provavelmente não deveria estar usando um desses métodos. Anti-Cross Site Scripting Biblioteca da Microsoft inclui substituições para HttpUtility.UrlEncode
e HttpUtility.HtmlEncode
que são ambos mais compatível com padrões, e mais seguro. Como um bônus, você tem um método JavaScriptEncode
também.
Server.UrlEncode () está lá para fornecer compatibilidade com ASP clássico,
Server.UrlEncode(str);
É equivalente a:
HttpUtility.UrlEncode(str, Response.ContentEncoding);
O mesmo, Server.UrlEncode()
chama HttpUtility.UrlEncode()