Pergunta

Existe uma diferença entre Server.UrlEncode e HttpUtility.UrlEncode?

Foi útil?

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 uma UriFormatException 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 uma UriFormatException 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()

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top