Codificação de URL usando C #

340

Eu tenho um aplicativo que envia uma solicitação POST ao software do fórum VB e efetua login em alguém (sem definir cookies ou qualquer coisa).

Depois que o usuário está logado, crio uma variável que cria um caminho em sua máquina local.

c: \ tempfolder \ date \ nome de usuário

O problema é que alguns nomes de usuário estão lançando a exceção "Caracteres ilegais". Por exemplo, se meu nome de usuário fosse mas|fenix, isso lançaria uma exceção ..

Path.Combine( _      
  Environment.GetFolderPath(System.Environment.SpecialFolder.CommonApplicationData), _
  DateTime.Now.ToString("ddMMyyhhmm") + "-" + form1.username)

Não quero removê-lo da string, mas uma pasta com seu nome de usuário é criada por FTP em um servidor. E isso leva à minha segunda pergunta. Se estou criando uma pasta no servidor, posso deixar os "caracteres ilegais" em? Só pergunto isso porque o servidor é baseado no Linux e não tenho certeza se o Linux aceita ou não.

EDIT: Parece que a codificação de URL NÃO é o que eu quero .. Aqui está o que eu quero fazer:

old username = mas|fenix
new username = mas%xxfenix

Onde% xx é o valor ASCII ou qualquer outro valor que identifique facilmente o caractere.

masfenix
fonte
Incorpore isso para tornar os nomes de pastas seguros do sistema de arquivos: http://stackoverflow.com/questions/333175/is-there-a-way-of-making-strings-file-path-safe-in-c
missaghi

Respostas:

191

Editar: observe que esta resposta está desatualizada. Veja a resposta de Siarhei Kuchuk abaixo para uma solução melhor

UrlEncoding fará o que você está sugerindo aqui. Com o C #, você simplesmente usa HttpUtility, como mencionado.

Você também pode regexar os caracteres ilegais e depois substituí-los, mas isso fica muito mais complexo, pois você terá que ter algum tipo de máquina de estado (alternar ... caso, por exemplo) para substituir pelos caracteres corretos. Como UrlEncodeisso é feito com antecedência, é bastante fácil.

Quanto ao Linux versus Windows, existem alguns caracteres aceitáveis ​​no Linux que não estão no Windows, mas eu não me preocuparia com isso, pois o nome da pasta pode ser retornado decodificando a string Url, usando UrlDecode, para que você possa percorrer o alterar.

Gregory A Beamer
fonte
5
esta resposta está desatualizada agora. ler algumas respostas abaixo - como de .net45 esta pode ser a solução correta: msdn.microsoft.com/en-us/library/...
blueberryfields
11
Para FTP, cada parte do Uri (nome da pasta ou arquivo) pode ser construída usando Uri.EscapeDataString (fileOrFolderName), permitindo todos os caracteres não compatíveis com o Uri (espaços, unicode ...). Por exemplo, para permitir qualquer caractere no nome do arquivo, use: req = (FtpWebRequest) WebRequest.Create (new Uri (caminho + "/" + Uri.EscapeDataString (nome do arquivo))); Usando HttpUtility.UrlEncode () substitua espaços por sinais de adição (+). Um comportamento correto para os mecanismos de pesquisa, mas incorreto para os nomes de arquivos / pastas.
Renaud Bancel
O asp.net bloqueia a maioria do xss em url quando você recebe um aviso quando tenta adicionar o script js A potentially dangerous Request.Path value was detected from the client.
Aprendo
510

Venho experimentando os vários métodos que o .NET fornece para codificação de URL. Talvez a tabela a seguir seja útil (como saída de um aplicativo de teste que escrevi):

Unencoded UrlEncoded UrlEncodedUnicode UrlPathEncoded EscapedDataString EscapedUriString HtmlEncoded HtmlAttributeEncoded HexEscaped
A         A          A                 A              A                 A                A           A                    %41
B         B          B                 B              B                 B                B           B                    %42

a         a          a                 a              a                 a                a           a                    %61
b         b          b                 b              b                 b                b           b                    %62

0         0          0                 0              0                 0                0           0                    %30
1         1          1                 1              1                 1                1           1                    %31

[space]   +          +                 %20            %20               %20              [space]     [space]              %20
!         !          !                 !              !                 !                !           !                    %21
"         %22        %22               "              %22               %22              "      "               %22
#         %23        %23               #              %23               #                #           #                    %23
$         %24        %24               $              %24               $                $           $                    %24
%         %25        %25               %              %25               %25              %           %                    %25
&         %26        %26               &              %26               &                &       &                %26
'         %27        %27               '              '                 '                '       '                %27
(         (          (                 (              (                 (                (           (                    %28
)         )          )                 )              )                 )                )           )                    %29
*         *          *                 *              %2A               *                *           *                    %2A
+         %2b        %2b               +              %2B               +                +           +                    %2B
,         %2c        %2c               ,              %2C               ,                ,           ,                    %2C
-         -          -                 -              -                 -                -           -                    %2D
.         .          .                 .              .                 .                .           .                    %2E
/         %2f        %2f               /              %2F               /                /           /                    %2F
:         %3a        %3a               :              %3A               :                :           :                    %3A
;         %3b        %3b               ;              %3B               ;                ;           ;                    %3B
<         %3c        %3c               <              %3C               %3C              &lt;        &lt;                 %3C
=         %3d        %3d               =              %3D               =                =           =                    %3D
>         %3e        %3e               >              %3E               %3E              &gt;        >                    %3E
?         %3f        %3f               ?              %3F               ?                ?           ?                    %3F
@         %40        %40               @              %40               @                @           @                    %40
[         %5b        %5b               [              %5B               %5B              [           [                    %5B
\         %5c        %5c               \              %5C               %5C              \           \                    %5C
]         %5d        %5d               ]              %5D               %5D              ]           ]                    %5D
^         %5e        %5e               ^              %5E               %5E              ^           ^                    %5E
_         _          _                 _              _                 _                _           _                    %5F
`         %60        %60               `              %60               %60              `           `                    %60
{         %7b        %7b               {              %7B               %7B              {           {                    %7B
|         %7c        %7c               |              %7C               %7C              |           |                    %7C
}         %7d        %7d               }              %7D               %7D              }           }                    %7D
~         %7e        %7e               ~              ~                 ~                ~           ~                    %7E

Ā         %c4%80     %u0100            %c4%80         %C4%80            %C4%80           Ā           Ā                    [OoR]
ā         %c4%81     %u0101            %c4%81         %C4%81            %C4%81           ā           ā                    [OoR]
Ē         %c4%92     %u0112            %c4%92         %C4%92            %C4%92           Ē           Ē                    [OoR]
ē         %c4%93     %u0113            %c4%93         %C4%93            %C4%93           ē           ē                    [OoR]
Ī         %c4%aa     %u012a            %c4%aa         %C4%AA            %C4%AA           Ī           Ī                    [OoR]
ī         %c4%ab     %u012b            %c4%ab         %C4%AB            %C4%AB           ī           ī                    [OoR]
Ō         %c5%8c     %u014c            %c5%8c         %C5%8C            %C5%8C           Ō           Ō                    [OoR]
ō         %c5%8d     %u014d            %c5%8d         %C5%8D            %C5%8D           ō           ō                    [OoR]
Ū         %c5%aa     %u016a            %c5%aa         %C5%AA            %C5%AA           Ū           Ū                    [OoR]
ū         %c5%ab     %u016b            %c5%ab         %C5%AB            %C5%AB           ū           ū                    [OoR]

As colunas representam codificações da seguinte maneira:

  • UrlEncoded: HttpUtility.UrlEncode

  • UrlEncodedUnicode: HttpUtility.UrlEncodeUnicode

  • UrlPathEncoded: HttpUtility.UrlPathEncode

  • EscapedDataString: Uri.EscapeDataString

  • EscapedUriString: Uri.EscapeUriString

  • HtmlEncoded: HttpUtility.HtmlEncode

  • HtmlAttributeEncoded: HttpUtility.HtmlAttributeEncode

  • HexEscaped: Uri.HexEscape

NOTAS:

  1. HexEscapepode lidar apenas com os primeiros 255 caracteres. Portanto, lança uma ArgumentOutOfRangeexceção para os caracteres latinos A-Extended (por exemplo, Ā).

  2. Esta tabela foi gerada no .NET 4.0 (consulte o comentário de Levi Botelho abaixo que diz que a codificação no .NET 4.5 é um pouco diferente).

EDITAR:

Adicionei uma segunda tabela com as codificações do .NET 4.5. Veja esta resposta: https://stackoverflow.com/a/21771206/216440

EDIT 2:

Como as pessoas parecem gostar dessas tabelas, pensei que você poderia gostar do código-fonte que gera a tabela, para que você possa se divertir. É um aplicativo de console simples em C #, que pode atingir o .NET 4.0 ou 4.5:

using System;
using System.Collections.Generic;
using System.Text;
// Need to add a Reference to the System.Web assembly.
using System.Web;

namespace UriEncodingDEMO2
{
    class Program
    {
        static void Main(string[] args)
        {
            EncodeStrings();

            Console.WriteLine();
            Console.WriteLine("Press any key to continue...");
            Console.Read();
        }

        public static void EncodeStrings()
        {
            string stringToEncode = "ABCD" + "abcd"
            + "0123" + " !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" + "ĀāĒēĪīŌōŪū";

            // Need to set the console encoding to display non-ASCII characters correctly (eg the 
            //  Latin A-Extended characters such as ĀāĒē...).
            Console.OutputEncoding = Encoding.UTF8;

            // Will also need to set the console font (in the console Properties dialog) to a font 
            //  that displays the extended character set correctly.
            // The following fonts all display the extended characters correctly:
            //  Consolas
            //  DejaVu Sana Mono
            //  Lucida Console

            // Also, in the console Properties, set the Screen Buffer Size and the Window Size 
            //  Width properties to at least 140 characters, to display the full width of the 
            //  table that is generated.

            Dictionary<string, Func<string, string>> columnDetails =
                new Dictionary<string, Func<string, string>>();
            columnDetails.Add("Unencoded", (unencodedString => unencodedString));
            columnDetails.Add("UrlEncoded",
                (unencodedString => HttpUtility.UrlEncode(unencodedString)));
            columnDetails.Add("UrlEncodedUnicode",
                (unencodedString => HttpUtility.UrlEncodeUnicode(unencodedString)));
            columnDetails.Add("UrlPathEncoded",
                (unencodedString => HttpUtility.UrlPathEncode(unencodedString)));
            columnDetails.Add("EscapedDataString",
                (unencodedString => Uri.EscapeDataString(unencodedString)));
            columnDetails.Add("EscapedUriString",
                (unencodedString => Uri.EscapeUriString(unencodedString)));
            columnDetails.Add("HtmlEncoded",
                (unencodedString => HttpUtility.HtmlEncode(unencodedString)));
            columnDetails.Add("HtmlAttributeEncoded",
                (unencodedString => HttpUtility.HtmlAttributeEncode(unencodedString)));
            columnDetails.Add("HexEscaped",
                (unencodedString
                    =>
                    {
                        // Uri.HexEscape can only handle the first 255 characters so for the 
                        //  Latin A-Extended characters, such as A, it will throw an 
                        //  ArgumentOutOfRange exception.                       
                        try
                        {
                            return Uri.HexEscape(unencodedString.ToCharArray()[0]);
                        }
                        catch
                        {
                            return "[OoR]";
                        }
                    }));

            char[] charactersToEncode = stringToEncode.ToCharArray();
            string[] stringCharactersToEncode = Array.ConvertAll<char, string>(charactersToEncode,
                (character => character.ToString()));
            DisplayCharacterTable<string>(stringCharactersToEncode, columnDetails);
        }

        private static void DisplayCharacterTable<TUnencoded>(TUnencoded[] unencodedArray,
            Dictionary<string, Func<TUnencoded, string>> mappings)
        {
            foreach (string key in mappings.Keys)
            {
                Console.Write(key.Replace(" ", "[space]") + " ");
            }
            Console.WriteLine();

            foreach (TUnencoded unencodedObject in unencodedArray)
            {
                string stringCharToEncode = unencodedObject.ToString();
                foreach (string columnHeader in mappings.Keys)
                {
                    int columnWidth = columnHeader.Length + 1;
                    Func<TUnencoded, string> encoder = mappings[columnHeader];
                    string encodedString = encoder(unencodedObject);

                    // ASSUMPTION: Column header will always be wider than encoded string.
                    Console.Write(encodedString.Replace(" ", "[space]").PadRight(columnWidth));
                }
                Console.WriteLine();
            }
        }
    }
}
Simon Tewsi
fonte
2
Esta é uma resposta fantástica. Acontece que eu queria usar o Uri.EscapeDataString e não incluir o System.Web. Obrigado por esta tabela.
Seravy
7
Observe que isso não é mais 100% exato. Certas funções mudaram ligeiramente entre o .NET 4 e o .NET 4.5. Consulte stackoverflow.com/q/20003106/1068266 .
Levi Botelho
2
@ Levi: Obrigado pela atenção. Adicionei uma segunda resposta com a tabela para o .NET 4.5. Editei a resposta original para vincular à segunda tabela.
Simon Tewsi
Observe que a documentação do .NET diz Não use; destina-se apenas à compatibilidade do navegador. Use UrlEncode. , mas esse método codifica muitos outros caracteres indesejados. O mais próximo é Uri.EscapeUriString, mas cuidado, ele não suporta um nullargumento.
Andrew
11
Eu esqueci de mencionar, meu comentário acima é para UrlPathEncode. Então, basicamente, substitua UrlPathEncodepor Uri.EscapeUriString.
Andrew
278

Você deve codificar apenas o nome de usuário ou outra parte do URL que possa ser inválida. URL que codifica um URL pode causar problemas, uma vez que algo como isto:

string url = HttpUtility.UrlEncode("http://www.google.com/search?q=Example");

Produzirá

http% 3a% 2f% 2fwww.google.com% 2fsearch% 3fq% 3dExemplo

Obviamente, isso não vai funcionar bem. Em vez disso, você deve codificar SOMENTE o valor do par de chave / valor na cadeia de consulta, desta forma:

string url = "http://www.google.com/search?q=" + HttpUtility.UrlEncode("Example");

Espero que ajude. Além disso, como teedyay mencionado, você ainda precisa fazer personagens de nome de arquivo certeza ilegais são removidos ou então o sistema de arquivos não vai gostar do caminho.

Dan Herbert
fonte
33
O uso do método HttpUtility.UrlPathEncode deve evitar o problema que você está descrevendo aqui.
vipirtti
12
@ DJ Pirtu: É verdade que o UrlPathEncode não fará essas alterações indesejadas no caminho, mas também não codificará nada após o ?(já que assume que a string de consulta já está codificada). No exemplo de Dan Herbert, parece que ele está fingindo Exampleser o texto que requer codificação, portanto HttpUtility.UrlPathEncode("http://www.google.com/search?q=Example");não funcionará. Experimente com ?q=Ex&ple(onde está o resultado desejado ?q=Ex%26ple). Não funcionará porque (1) UrlPathEncode não toca em nada depois ?e (2) UrlPathEncode não codifica de &qualquer maneira.
Tim Goodman
11
Veja aqui: connect.microsoft.com/VisualStudio/feedback/details/551839/… Devo acrescentar que é bom que UrlPathEncode não codifique &, porque você precisa delimitar os parâmetros da string de consulta. Mas há momentos em que você também deseja e comercial codificado.
Tim Goodman
10
HttpUtility é sucedido por WebUtility em versões mais recentes, poupar algum tempo :)
Wiseman
190

Melhor maneira é usar

Uri.EscapeUriString

para não fazer referência ao perfil completo de .net 4.

Siarhei Kuchuk
fonte
11
Concordo totalmente pois muitas vezes o "perfil de cliente" é suficiente para aplicativos usando System.Net mas não usando System.Web ;-)
hfrmobile
6
O OP está falando em verificar a compatibilidade do sistema de arquivos, para que isso não funcione. O conjunto de caracteres não permitido do Windows é '["/", "\\", "<", ">", ":", "\" "," | ","? "," * "]', Mas muitos deles não seja codificado usando EscapedUriString (veja a tabela abaixo - obrigado por essa tabela @ Simon Tewsi) ... "cria um caminho na máquina local" -OP UrlEncoded cuida de quase todos os problemas, mas não resolve o problema. problema com "%" ou "% 3-F" estar na entrada original, como uma "descodificar" irá agora ser diferente do inicial.
m1m1k
6
só para deixar claro: ESTE TRABALHO resposta WONT para sistemas de arquivos
m1m1k
11
Além disso, a partir do .NET Framework 4.5, o perfil do cliente foi descontinuado e apenas o pacote redistribuível completo está disponível.
Twomm
29
stackoverflow.com/a/34189188/3436164 Use Uri.EscapeDataStringNÃO Uri.EscapeUriStringLeia este comentário, ele me ajudou.
ykadaru 13/03/19
181

Desde o .NET Framework 4.5 e o .NET Standard 1.0, você deve usar WebUtility.UrlEncode. Vantagens sobre alternativas:

  1. Faz parte do .NET Framework 4.5+, .NET Core 1.0+, .NET Standard 1.0+, UWP 10.0+ e todas as plataformas Xamarin. HttpUtility, embora esteja disponível no .NET Framework anterior (.NET Framework 1.1+), fica disponível em outras plataformas muito mais tarde (.NET Core 2.0+, .NET Standard 2.0+) e ainda está indisponível no UWP (consulte a pergunta relacionada ).

  2. No .NET Framework, ele reside emSystem.dll , portanto, não requer nenhuma referência adicional, ao contrário HttpUtility.

  3. Diferentemente, ele escapa caracteres para URLsUri.EscapeUriString (veja os comentários na resposta de drweb86 ).

  4. Ela não possui limites no comprimento da string , ao contrário Uri.EscapeDataString(consulte a pergunta relacionada ), portanto pode ser usada para solicitações POST, por exemplo.

Athari
fonte
Eu gosto da maneira como ele codifica usando "+" em vez de% 20 para espaços .. mas esse ainda não remove "da URL e me dá uma URL inválida ... oh bem ... só vou ter que fazer uma substituição (" "" "", "")
Piotr Kula
84

Levi Botelho comentou que a tabela de codificações geradas anteriormente não é mais precisa para o .NET 4.5, uma vez que as codificações mudaram ligeiramente entre o .NET 4.0 e o 4.5. Então, eu regenerei a tabela para o .NET 4.5:

Unencoded UrlEncoded UrlEncodedUnicode UrlPathEncoded WebUtilityUrlEncoded EscapedDataString EscapedUriString HtmlEncoded HtmlAttributeEncoded WebUtilityHtmlEncoded HexEscaped
A         A          A                 A              A                    A                 A                A           A                    A                     %41
B         B          B                 B              B                    B                 B                B           B                    B                     %42

a         a          a                 a              a                    a                 a                a           a                    a                     %61
b         b          b                 b              b                    b                 b                b           b                    b                     %62

0         0          0                 0              0                    0                 0                0           0                    0                     %30
1         1          1                 1              1                    1                 1                1           1                    1                     %31

[space]   +          +                 %20            +                    %20               %20              [space]     [space]              [space]               %20
!         !          !                 !              !                    %21               !                !           !                    !                     %21
"         %22        %22               "              %22                  %22               %22              &quot;      &quot;               &quot;                %22
#         %23        %23               #              %23                  %23               #                #           #                    #                     %23
$         %24        %24               $              %24                  %24               $                $           $                    $                     %24
%         %25        %25               %              %25                  %25               %25              %           %                    %                     %25
&         %26        %26               &              %26                  %26               &                &amp;       &amp;                &amp;                 %26
'         %27        %27               '              %27                  %27               '                &#39;       &#39;                &#39;                 %27
(         (          (                 (              (                    %28               (                (           (                    (                     %28
)         )          )                 )              )                    %29               )                )           )                    )                     %29
*         *          *                 *              *                    %2A               *                *           *                    *                     %2A
+         %2b        %2b               +              %2B                  %2B               +                +           +                    +                     %2B
,         %2c        %2c               ,              %2C                  %2C               ,                ,           ,                    ,                     %2C
-         -          -                 -              -                    -                 -                -           -                    -                     %2D
.         .          .                 .              .                    .                 .                .           .                    .                     %2E
/         %2f        %2f               /              %2F                  %2F               /                /           /                    /                     %2F
:         %3a        %3a               :              %3A                  %3A               :                :           :                    :                     %3A
;         %3b        %3b               ;              %3B                  %3B               ;                ;           ;                    ;                     %3B
<         %3c        %3c               <              %3C                  %3C               %3C              &lt;        &lt;                 &lt;                  %3C
=         %3d        %3d               =              %3D                  %3D               =                =           =                    =                     %3D
>         %3e        %3e               >              %3E                  %3E               %3E              &gt;        >                    &gt;                  %3E
?         %3f        %3f               ?              %3F                  %3F               ?                ?           ?                    ?                     %3F
@         %40        %40               @              %40                  %40               @                @           @                    @                     %40
[         %5b        %5b               [              %5B                  %5B               [                [           [                    [                     %5B
\         %5c        %5c               \              %5C                  %5C               %5C              \           \                    \                     %5C
]         %5d        %5d               ]              %5D                  %5D               ]                ]           ]                    ]                     %5D
^         %5e        %5e               ^              %5E                  %5E               %5E              ^           ^                    ^                     %5E
_         _          _                 _              _                    _                 _                _           _                    _                     %5F
`         %60        %60               `              %60                  %60               %60              `           `                    `                     %60
{         %7b        %7b               {              %7B                  %7B               %7B              {           {                    {                     %7B
|         %7c        %7c               |              %7C                  %7C               %7C              |           |                    |                     %7C
}         %7d        %7d               }              %7D                  %7D               %7D              }           }                    }                     %7D
~         %7e        %7e               ~              %7E                  ~                 ~                ~           ~                    ~                     %7E

Ā         %c4%80     %u0100            %c4%80         %C4%80               %C4%80            %C4%80           Ā           Ā                    Ā                     [OoR]
ā         %c4%81     %u0101            %c4%81         %C4%81               %C4%81            %C4%81           ā           ā                    ā                     [OoR]
Ē         %c4%92     %u0112            %c4%92         %C4%92               %C4%92            %C4%92           Ē           Ē                    Ē                     [OoR]
ē         %c4%93     %u0113            %c4%93         %C4%93               %C4%93            %C4%93           ē           ē                    ē                     [OoR]
Ī         %c4%aa     %u012a            %c4%aa         %C4%AA               %C4%AA            %C4%AA           Ī           Ī                    Ī                     [OoR]
ī         %c4%ab     %u012b            %c4%ab         %C4%AB               %C4%AB            %C4%AB           ī           ī                    ī                     [OoR]
Ō         %c5%8c     %u014c            %c5%8c         %C5%8C               %C5%8C            %C5%8C           Ō           Ō                    Ō                     [OoR]
ō         %c5%8d     %u014d            %c5%8d         %C5%8D               %C5%8D            %C5%8D           ō           ō                    ō                     [OoR]
Ū         %c5%aa     %u016a            %c5%aa         %C5%AA               %C5%AA            %C5%AA           Ū           Ū                    Ū                     [OoR]
ū         %c5%ab     %u016b            %c5%ab         %C5%AB               %C5%AB            %C5%AB           ū           ū                    ū                     [OoR]

As colunas representam codificações da seguinte maneira:

  • UrlEncoded: HttpUtility.UrlEncode
  • UrlEncodedUnicode: HttpUtility.UrlEncodeUnicode
  • UrlPathEncoded: HttpUtility.UrlPathEncode
  • WebUtilityUrlEncoded: WebUtility.UrlEncode
  • EscapedDataString: Uri.EscapeDataString
  • EscapedUriString: Uri.EscapeUriString
  • HtmlEncoded: HttpUtility.HtmlEncode
  • HtmlAttributeEncoded: HttpUtility.HtmlAttributeEncode
  • WebUtilityHtmlEncoded: WebUtility.HtmlEncode
  • HexEscaped: Uri.HexEscape

NOTAS:

  1. O HexEscape pode manipular apenas os primeiros 255 caracteres. Portanto, lança uma exceção ArgumentOutOfRange para os caracteres latinos A-Extended (por exemplo, Ā).

  2. Esta tabela foi gerada no .NET 4.5 (consulte a resposta https://stackoverflow.com/a/11236038/216440 para obter as codificações relevantes para o .NET 4.0 e abaixo).

EDITAR:

  1. Como resultado da resposta do Discord, adicionei os novos métodos WebUtility UrlEncode e HtmlEncode, que foram introduzidos no .NET 4.5.
Simon Tewsi
fonte
2
Não, não o usuário UrlPathEncode - até o MSDN diz que não deve ser usado. Foi criada
Jeff Jeff
O Server.URLEncode é outra variação desse tema? Isso gera alguma saída diferente?
ALEXintlsos
2
@ALEX: No ASP.NET, o objeto Server é uma instância do HttpServerUtility. Usando o descompilador dotPeek, observei HttpServerUtility.UrlEncode. Apenas chama HttpUtility.UrlEncode, para que a saída dos dois métodos seja idêntica.
Simon Tewsi
Parece que, mesmo com essa superabundância de métodos de codificação, todos eles ainda falham de maneira espetacular para algo acima do Latin-1, como → ou ☠. (UrlEncodedUnicode parece que pelo menos tenta oferecer suporte a Unicode, mas está obsoleto / ausente.) #
Brianary
Simon, você pode simplesmente integrar esta resposta na resposta aceita? será bom tê-lo em uma resposta. você pode integrá-lo e criar um cabeçalho h1 na parte inferior dessa resposta, ou integrar em uma tabela e marcar linhas diferentes, como: (Net4.0) ? %3f................................ (Net4.5) ? %3f ..................................
T.Todua
60

A codificação de URL é fácil no .NET. Usar:

System.Web.HttpUtility.UrlEncode(string url)

Se isso for decodificado para obter o nome da pasta, você ainda precisará excluir caracteres que não podem ser usados ​​nos nomes das pastas (*,?, /, Etc.)

teedyay
fonte
Ele codifica todos os caracteres que não fazem parte do alfabeto?
masfenix
11
A codificação de URL converte caracteres que não são permitidos em um URL em equivalentes de entidade de caracteres. Lista de caracteres inseguros: blooberry.com/indexdot/html/topics/urlencoding.htm
Ian Robinson
MSDN Fazer a ligação em HttpUtility.UrlEncode: msdn.microsoft.com/en-us/library/4fkewx0t.aspx
Ian Robinson
11
É uma boa prática para colocar o System.Web completa ... parte em sua resposta, ele salva um monte de gente um pouco de tempo :) graças
Liam
3
Isso é perigoso: nem todos os caracteres da URL precisam ser codificados, apenas os valores dos parâmetros da querystring. A maneira que você sugere também codificará o & que é necessário para criar vários parâmetros na string de consulta. O soution é para codificar cada valor de parâmetros, se necessário
Marco Staffoli
12

Se você não conseguir ver o System.Web, altere as configurações do projeto. A estrutura de destino deve ser ".NET Framework 4" em vez de ".NET Framework 4 Client Profile"

útil
fonte
11
Na minha opinião, os desenvolvedores devem saber sobre ".NET Profiles" e devem usar o correto para seus propósitos! Apenas adicionar o perfil completo para obter (por exemplo, System.Web) sem realmente saber por que eles adicionam o perfil completo, não é muito inteligente. Use o "Perfil do Cliente" para seus aplicativos clientes e o perfil completo somente quando necessário (por exemplo, um cliente WinForms ou WPF deve usar o perfil do cliente e não o perfil completo)! Por exemplo, não vejo um motivo para usar o HttpServerUtility em um aplicativo cliente ^^ ... se isso for necessário, há algo errado com o design do aplicativo!
Hfrmobile 26/10/12
4
Mesmo? Você nunca vê a necessidade de um aplicativo cliente construir um URL? O que você faz para viver - como zelador?
sproketboy
@hfrmobile: não. Está tudo errado com o modelo de perfil (que viveu apenas uma vez e foi abandonado na próxima versão). E isso era óbvio desde o começo. É óbvio para você agora? Pense primeiro, não aceite tudo "como está" o que o msft tenta vender; P
abatishchev
Desculpe, mas nunca disse que um cliente nunca precisa criar / usar um URL. Enquanto o .NET 4.0 estiver em uso, o usuário deverá se preocupar com isso. Para resumir: os desenvolvedores devem pensar duas vezes antes de adicionar o HttpServerUtility a um cliente. Existem outras / melhores maneiras, basta ver a resposta com 139 votos ou "Desde o .NET Framework 4.5, você pode usar o WebUtility.UrlEncode. Primeiro, ele reside no System.dll, portanto, não requer referências adicionais.".
Hfrmobile
9

A implementação do .NET UrlEncodenão está em conformidade com a RFC 3986.

  1. Alguns caracteres não são codificados, mas deveriam ser. Os !()*caracteres estão listados na seção 2.2 da RFC como caracteres reservados que devem ser codificados, mas o .NET falha ao codificar esses caracteres.

  2. Alguns caracteres são codificados, mas não devem ser. Os .-_caracteres não estão listados na seção 2.2 da RFC como um caractere reservado que ainda não deve ser codificado. O .NET codifica erroneamente esses caracteres.

  3. O RFC especifica que, para serem consistentes, as implementações devem usar HEXDIG em maiúsculas, onde o .NET produz HEXDIG em minúsculas.

Charlie
fonte
4

Acho que as pessoas aqui foram desviadas pela mensagem UrlEncode. URLEncoding não é o que você deseja - você deseja codificar coisas que não funcionarão como um nome de arquivo no sistema de destino.

Supondo que você queira alguma generalidade - fique à vontade para encontrar os caracteres ilegais em vários sistemas (MacOS, Windows, Linux e Unix), junte-os para formar um conjunto de caracteres para escapar.

Quanto à fuga, um HexEscape deve ficar bem (Substituindo os caracteres por% XX). Converta cada caractere em bytes UTF-8 e codifique tudo> 128 se desejar oferecer suporte a sistemas que não executam unicode. Porém, existem outras maneiras, como usar barras invertidas "\" ou codificação HTML "" ". Você pode criar o seu próprio. Tudo o que qualquer sistema precisa fazer é 'codificar' o caractere incompatível. Os sistemas acima permitem recriar o nome original - mas algo como substituir os caracteres incorretos por espaços também funciona.

Na mesma tangente acima, o único a ser usado é

Uri.EscapeDataString

- Ele codifica tudo o que é necessário para o OAuth, não codifica o que o OAuth proíbe codificar e codifica o espaço como% 20 e não + (também na especificação OATH) Consulte: RFC 3986. AFAIK, este é o última especificação de URI.

Gerard ONeill
fonte
3

Eu escrevi um método C # que codifica url TODOS os símbolos:

    /// <summary>
    /// !#$345Hf} → %21%23%24%33%34%35%48%66%7D
    /// </summary>
    public static string UrlEncodeExtended( string value )
    {
        char[] chars = value.ToCharArray();
        StringBuilder encodedValue = new StringBuilder();
        foreach (char c in chars)
        {
            encodedValue.Append( "%" + ( (int)c ).ToString( "X2" ) );
        }
        return encodedValue.ToString();
    }
Sergey
fonte
1

Idealmente, eles iriam para uma classe chamada "FileNaming" ou talvez apenas renomear Encode para "FileNameEncode". Nota: eles não foram projetados para lidar com caminhos completos, apenas os nomes de pastas e / ou arquivos. Idealmente, você deve dividir ("/") seu caminho completo primeiro e depois verificar as peças. E, obviamente, em vez de uma união, você pode simplesmente adicionar o caractere "%" à ​​lista de caracteres não permitidos no Windows, mas acho que é mais útil / legível / factual dessa maneira. Decode () é exatamente o mesmo, mas alterna o Substituir (Uri.HexEscape (s [0]), s) "escapou" com o caractere.

public static List<string> urlEncodedCharacters = new List<string>
{
  "/", "\\", "<", ">", ":", "\"", "|", "?", "%" //and others, but not *
};
//Since this is a superset of urlEncodedCharacters, we won't be able to only use UrlEncode() - instead we'll use HexEncode
public static List<string> specialCharactersNotAllowedInWindows = new List<string>
{
  "/", "\\", "<", ">", ":", "\"", "|", "?", "*" //windows dissallowed character set
};

    public static string Encode(string fileName)
    {
        //CheckForFullPath(fileName); // optional: make sure it's not a path?
        List<string> charactersToChange = new List<string>(specialCharactersNotAllowedInWindows);
        charactersToChange.AddRange(urlEncodedCharacters.
            Where(x => !urlEncodedCharacters.Union(specialCharactersNotAllowedInWindows).Contains(x)));   // add any non duplicates (%)

        charactersToChange.ForEach(s => fileName = fileName.Replace(s, Uri.HexEscape(s[0])));   // "?" => "%3f"

        return fileName;
    }

Obrigado @ simon-tewsi pela tabela muito útil acima!

m1m1k
fonte
também útil: Path.GetInvalidFileNameChars()
m1m1k
sim. Aqui está uma maneira de fazer isso: foreach (char c em System.IO.Path.GetInvalidFileNameChars ()) {filename = filename.Replace (c, '_'); }
net
0

Além da resposta de Dan Herbert, você deve codificar apenas os valores em geral.

Split possui o parâmetro params Split ('&', '='); expressão primeiramente dividida por & then '=', para que elementos ímpares sejam todos os valores a serem codificados, mostrados abaixo.

public static void EncodeQueryString(ref string queryString)
{
    var array=queryString.Split('&','=');
    for (int i = 0; i < array.Length; i++) {
        string part=array[i];
        if(i%2==1)
        {               
            part=System.Web.HttpUtility.UrlEncode(array[i]);
            queryString=queryString.Replace(array[i],part);
        }
    }
}
Davut Gürbüz
fonte