Codificación de URL usando C #

340

Tengo una aplicación que envía una solicitud POST al software del foro VB e inicia sesión en alguien (sin configurar cookies ni nada).

Una vez que el usuario ha iniciado sesión, creo una variable que crea una ruta en su máquina local.

c: \ tempfolder \ date \ username

El problema es que algunos nombres de usuario arrojan una excepción de "caracteres ilegales". Por ejemplo, si mi nombre de usuario fuera mas|fenix, arrojaría una excepción.

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

No quiero eliminarlo de la cadena, pero se crea una carpeta con su nombre de usuario a través de FTP en un servidor. Y esto lleva a mi segunda pregunta. Si estoy creando una carpeta en el servidor, ¿puedo dejar los "caracteres ilegales"? Solo pregunto esto porque el servidor está basado en Linux, y no estoy seguro de si Linux lo acepta o no.

EDITAR: Parece que la codificación de URL NO es lo que quiero ... Esto es lo que quiero hacer:

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

Donde% xx es el valor ASCII o cualquier otro valor que pueda identificar fácilmente al personaje.

Masfenix
fuente
Incorpore esto para hacer que los nombres de carpetas seguros del sistema de archivos: http://stackoverflow.com/questions/333175/is-there-a-way-of-making-strings-file-path-safe-in-c
missaghi

Respuestas:

191

Editar: Tenga en cuenta que esta respuesta ahora está desactualizada. Vea la respuesta de Siarhei Kuchuk a continuación para una mejor solución

UrlEncoding hará lo que sugieres aquí. Con C #, simplemente usa HttpUtility, como se mencionó.

También puede regexificar los caracteres ilegales y luego reemplazarlos, pero esto se vuelve mucho más complejo, ya que tendrá que tener alguna forma de máquina de estado (cambiar ... mayúsculas y minúsculas, por ejemplo) para reemplazar con los caracteres correctos. Como UrlEncodehace esto por adelantado, es bastante fácil.

En cuanto a Linux frente a Windows, hay algunos caracteres que son aceptables en Linux que no están en Windows, pero no me preocuparía por eso, ya que el nombre de la carpeta puede devolverse decodificando la cadena Url, usando UrlDecode, para que pueda hacer un viaje de ida y vuelta. cambios

Gregory A Beamer
fuente
55
Esta respuesta está desactualizada ahora. lea algunas respuestas a continuación: a partir de .net45, esta podría ser la solución correcta: msdn.microsoft.com/en-us/library/…
blueberryfields
1
Para FTP, cada parte de Uri (nombre de carpeta o archivo) puede construirse usando Uri.EscapeDataString (fileOrFolderName) permitiendo todos los caracteres no compatibles con Uri (espacios, unicode ...). Por ejemplo, para permitir cualquier carácter en el nombre de archivo, use: req = (FtpWebRequest) WebRequest.Create (nuevo Uri (ruta + "/" + Uri.EscapeDataString (nombre de archivo))); Usando HttpUtility.UrlEncode () reemplace los espacios con signos más (+). Un comportamiento correcto para los motores de búsqueda pero incorrecto para los nombres de archivo / carpeta.
Renaud Bancel
asp.net bloquea la mayoría de xss en la URL a medida que recibe una advertencia cuando intenta agregar un script js A potentially dangerous Request.Path value was detected from the client.
Aprendizaje del
510

He estado experimentando con los diversos métodos que proporciona .NET para la codificación de URL. Quizás la siguiente tabla sea útil (como resultado de una aplicación de prueba que escribí):

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]

Las columnas representan codificaciones de la siguiente manera:

  • 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. HexEscapesolo puede manejar los primeros 255 caracteres. Por lo tanto, arroja una ArgumentOutOfRangeexcepción para los caracteres latinos A-Extended (por ejemplo, Ā).

  2. Esta tabla se generó en .NET 4.0 (vea el comentario de Levi Botelho a continuación que dice que la codificación en .NET 4.5 es ligeramente diferente).

EDITAR:

Agregué una segunda tabla con las codificaciones para .NET 4.5. Vea esta respuesta: https://stackoverflow.com/a/21771206/216440

EDITAR 2:

Como la gente parece apreciar estas tablas, pensé que les gustaría el código fuente que genera la tabla, para que puedan jugar con ustedes. Es una aplicación de consola C # simple, que puede apuntar a .NET 4.0 o 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
fuente
2
Esta es una respuesta fantástica. Resulta que quería usar Uri.EscapeDataString y no incluir System.Web. Gracias por esta mesa.
Seravy
77
Tenga en cuenta que esto ya no es 100% preciso. Ciertas funciones han cambiado ligeramente entre .NET 4 y .NET 4.5. Ver stackoverflow.com/q/20003106/1068266 .
Levi Botelho
2
@Levi: Gracias por el aviso. Agregué una segunda respuesta con la tabla para .NET 4.5. He editado la respuesta original para vincular a la segunda tabla.
Simon Tewsi
Tenga en cuenta que la documentación de .NET dice No usar; destinado solo a la compatibilidad del navegador. Use UrlEncode. , pero ese método codifica muchos otros caracteres no deseados. El más cercano es Uri.EscapeUriString, pero cuidado, no admite nullargumentos.
Andrew
1
Olvidé mencionar, mi comentario anterior es para UrlPathEncode. Entonces, básicamente, reemplace UrlPathEncodecon Uri.EscapeUriString.
Andrew
278

Debe codificar solo el nombre de usuario u otra parte de la URL que podría ser inválida. La codificación de una URL puede generar problemas, ya que algo como esto:

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

Rendirá

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

Obviamente, esto no va a funcionar bien. En su lugar, debe codificar SOLO el valor del par clave / valor en la cadena de consulta, así:

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

Espero que eso ayude. Además, como mencionó teedyay , aún deberá asegurarse de que se eliminen los caracteres ilegales de nombre de archivo o de lo contrario el sistema de archivos no le gustará la ruta.

Dan Herbert
fuente
33
El uso del método HttpUtility.UrlPathEncode debería evitar el problema que está describiendo aquí.
vipirtti
12
@DJ Pirtu: Es cierto que UrlPathEncode no realizará esos cambios no deseados en la ruta, sin embargo, tampoco codificará nada después de ?(ya que supone que la cadena de consulta ya está codificada). En el ejemplo de Dan Herbert, parece que está fingiendo que Examplees el texto que requiere codificación, por HttpUtility.UrlPathEncode("http://www.google.com/search?q=Example");lo que no funcionará. Pruébelo con ?q=Ex&ple(donde está el resultado deseado ?q=Ex%26ple). No funcionará porque (1) UrlPathEncode no toca nada después ?, y (2) UrlPathEncode no codifica de &todos modos.
Tim Goodman el
1
Vea aquí: connect.microsoft.com/VisualStudio/feedback/details/551839/… Debo agregar que, por supuesto, es bueno que UrlPathEncode no codifique &, porque lo necesita para delimitar sus parámetros de cadena de consulta. Pero hay momentos en los que también quieres símbolos codificados.
Tim Goodman el
10
HttpUtility es sucedido por WebUtility en las últimas versiones, ahorre algo de tiempo :)
Wiseman
190

La mejor manera es usar

Uri.EscapeUriString

no hacer referencia al perfil completo de .net 4.

Siarhei Kuchuk
fuente
1
Totalmente de acuerdo ya que a menudo el "Perfil del cliente" es suficiente para las aplicaciones que usan System.Net pero no usan System.Web ;-)
hfrmobile
66
OP está hablando de verificar la compatibilidad del sistema de archivos, por lo que esto no funcionará. El conjunto de caracteres no permitidos de Windows es '["/", "\\", "<", ">", ":", "\" "," | ","? "," * "]' Pero muchos de estos no se codifique con EscapedUriString (consulte la tabla a continuación, gracias por esa tabla @Simon Tewsi) ... "crea una ruta en su máquina local" -OP UrlEncoded se encarga de casi todos los problemas, pero no resuelve el problema problema con "%" o "% 3f" en la entrada original, ya que una "decodificación" ahora será diferente a la original.
m1m1k
66
solo para que quede claro: ESTA respuesta NO FUNCIONARÁ para los sistemas de archivos
m1m1k
1
Además, comenzando con .NET Framework 4.5, el perfil del cliente ha sido descontinuado y solo está disponible el paquete redistribuible completo.
twomm
29
stackoverflow.com/a/34189188/3436164 Usar Uri.EscapeDataStringNO Uri.EscapeUriStringLeer este comentario, me ayudó.
ykadaru
181

Desde .NET Framework 4.5 y .NET Standard 1.0 debe usar WebUtility.UrlEncode. Ventajas sobre alternativas:

  1. Forma parte de .NET Framework 4.5+, .NET Core 1.0+, .NET Standard 1.0+, UWP 10.0+ y todas las plataformas Xamarin también. HttpUtility, aunque está disponible en .NET Framework anteriormente (.NET Framework 1.1+), está disponible en otras plataformas mucho más tarde (.NET Core 2.0+, .NET Standard 2.0+) y todavía no está disponible en UWP (consulte la pregunta relacionada ).

  2. En .NET Framework, reside en élSystem.dll , por lo que no requiere referencias adicionales, a diferencia de HttpUtility.

  3. Se escapa correctamente los caracteres para las URL , a diferencia de Uri.EscapeUriString(ver comentarios a la respuesta de drweb86 ).

  4. No tiene ningún límite en la longitud de la cadena , a diferencia de Uri.EscapeDataString(vea la pregunta relacionada ), por lo que puede usarse para solicitudes POST, por ejemplo.

Athari
fuente
Me gusta la forma en que codifica usando "+" en lugar de% 20 para espacios ... pero este todavía no elimina "de la URL y me da una URL no válida ... bueno, solo tendré que hacer un reemplazo (" "" "", "")
Piotr Kula
84

Levi Botelho comentó que la tabla de codificaciones que se generó anteriormente ya no es precisa para .NET 4.5, ya que las codificaciones cambiaron ligeramente entre .NET 4.0 y 4.5. Así que he regenerado la tabla para .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]

Las columnas representan codificaciones de la siguiente manera:

  • 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. HexEscape solo puede manejar los primeros 255 caracteres. Por lo tanto, arroja una excepción ArgumentOutOfRange para los caracteres latinos A-Extended (por ejemplo, Ā).

  2. Esta tabla se generó en .NET 4.5 (consulte la respuesta https://stackoverflow.com/a/11236038/216440 para las codificaciones relevantes para .NET 4.0 y versiones posteriores).

EDITAR:

  1. Como resultado de la respuesta de Discord, agregué los nuevos métodos WebUtility UrlEncode y HtmlEncode, que se introdujeron en .NET 4.5.
Simon Tewsi
fuente
2
No, no el usuario UrlPathEncode, incluso el MSDN dice que no debe usarse. Fue construido para solucionar un problema con netscape 2 msdn.microsoft.com/en-us/library/…
Jeff
¿Server.URLEncode es otra variación más de este tema? ¿Genera alguna salida diferente?
ALEXintlsos
2
@ALEX: en ASP.NET, el objeto Servidor es una instancia de HttpServerUtility. Usando el descompilador dotPeek, eché un vistazo a HttpServerUtility.UrlEncode. Simplemente llama a HttpUtility.UrlEncode para que la salida de los dos métodos sea idéntica.
Simon Tewsi
Parece que, incluso con esta sobreabundancia de métodos de codificación, todos fallan de manera espectacular para cualquier cosa por encima de Latin-1, como → o ☠. (UrlEncodedUnicode parece que al menos intenta admitir Unicode, pero está en desuso / falta.)
brianary
Simon, ¿puedes integrar esta respuesta en la respuesta aceptada? Será bueno tenerlo en una respuesta. podría integrarlo y hacer un encabezado h1 en la parte inferior de esa respuesta, o integrarlo en una tabla, y marcar diferentes líneas, como: (Net4.0) ? %3f................................ (Net4.5) ? %3f ..................................
T.Todua
60

La codificación de URL es fácil en .NET. Utilizar:

System.Web.HttpUtility.UrlEncode(string url)

Si se decodifica para obtener el nombre de la carpeta, aún deberá excluir los caracteres que no se pueden usar en los nombres de carpeta (*,?, /, Etc.)

teedyay
fuente
¿Codifica cada carácter que no es parte del alfabeto?
masfenix
1
La codificación de URL convierte los caracteres que no están permitidos en una URL en equivalentes de entidad de caracteres. Lista de caracteres inseguros: blooberry.com/indexdot/html/topics/urlencoding.htm
Ian Robinson
MSDN Link en HttpUtility.UrlEncode: msdn.microsoft.com/en-us/library/4fkewx0t.aspx
Ian Robinson
11
Es una buena práctica poner el sistema completo. Web ... parte de su respuesta, le ahorra a mucha gente un poco de tiempo :) gracias
Liam el
3
Esto es peligroso: no todos los caracteres de la url deben codificarse, solo los valores de los parámetros de la cadena de consulta. La forma en que sugiera codificará también el & que se necesita para crear múltiples parámetros en la cadena de consulta. El objetivo es codificar cada valor de los parámetros si es necesario
Marco Staffoli
12

Si no puede ver System.Web, cambie la configuración de su proyecto. El marco de destino debe ser ".NET Framework 4" en lugar de ".NET Framework 4 Client Profile"

útil
fuente
1
En mi opinión, los desarrolladores deberían saber sobre ".NET Profiles" y ¡deberían usar el correcto para sus propósitos! Simplemente agregar el perfil completo para obtener (por ejemplo, System.Web) sin saber realmente por qué agregan el perfil completo, no es muy inteligente. Use "Perfil de cliente" para sus aplicaciones de cliente y el perfil completo solo cuando sea necesario (por ejemplo, un cliente WinForms o WPF debe usar el perfil de cliente y no el perfil completo). por ejemplo, no veo una razón para usar HttpServerUtility en una aplicación cliente ^^ ... si esto es necesario, entonces hay algo mal con el diseño de la aplicación.
hfrmobile
44
De Verdad? ¿Nunca ve la necesidad de una aplicación cliente para construir una URL? ¿A qué te dedicas: tareas de limpieza?
sproketboy
@hfrmobile: no. Todo está mal con el modelo de perfil (que vivió solo una vez y fue abandonado en la próxima versión). Y fue obvio desde el principio. ¿Es obvio para ti ahora? Piense primero, no acepte todo 'como está' lo que msft intenta venderle; P
abatishchev
Lo siento, pero nunca dije que un cliente nunca tiene que construir / usar una URL. Mientras .NET 4.0 esté en uso, el usuario debería preocuparse por ello. En pocas palabras: los desarrolladores deberían pensarlo dos veces antes de agregar HttpServerUtility a un cliente. Hay otras / mejores formas, solo vea la respuesta con 139 votos o "Desde .NET Framework 4.5 puede usar WebUtility.UrlEncode. Primero, reside en System.dll, por lo que no requiere referencias adicionales".
hfrmobile
9

La implementación de .NET UrlEncodeno cumple con RFC 3986.

  1. Algunos caracteres no están codificados pero deberían estarlo. Los !()*caracteres se enumeran en la sección 2.2 del RFC como caracteres reservados que deben codificarse, pero .NET no puede codificar estos caracteres.

  2. Algunos caracteres están codificados pero no deberían estarlo. Los .-_caracteres no se enumeran en la sección 2.2 del RFC como un carácter reservado que aún no debe codificarse .NET codifica erróneamente estos caracteres.

  3. El RFC especifica que para ser consistentes, las implementaciones deben usar HEXDIG en mayúsculas, donde .NET produce HEXDIG en minúsculas.

Charlie
fuente
4

Creo que la gente aquí se desvió por el mensaje de UrlEncode. URLEncoding no es lo que desea: desea codificar cosas que no funcionarán como un nombre de archivo en el sistema de destino.

Suponiendo que desea algo de generalidad: siéntase libre de encontrar los caracteres ilegales en varios sistemas (MacOS, Windows, Linux y Unix), unirlos para formar un conjunto de caracteres para escapar.

En cuanto a la fuga, un HexEscape debería estar bien (Reemplazar los caracteres con% XX). Convierta cada carácter a bytes UTF-8 y codifique todo> 128 si desea admitir sistemas que no hacen unicode. Pero hay otras formas, como usar barras diagonales "\" o codificación HTML "" ". Puede crear la suya propia. Todo lo que tiene que hacer cualquier sistema es 'codificar' el carácter incompatible. Los sistemas anteriores le permiten recrear el nombre original, pero también funciona algo así como reemplazar los caracteres malos con espacios.

En la misma tangente que la anterior, la única para usar es

Uri.EscapeDataString

- Codifica todo lo que se necesita para OAuth, no codifica las cosas que OAuth prohíbe la codificación, y codifica el espacio como% 20 y no + (también en la especificación OATH) Ver: RFC 3986. AFAIK, este es el última especificación de URI.

Gerard ONeill
fuente
3

He escrito un método C # que codifica url TODOS los 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
fuente
1

Idealmente, estos irían en una clase llamada "FileNaming" o tal vez simplemente cambien el nombre de Encode a "FileNameEncode". Nota: estos no están diseñados para manejar rutas completas, solo los nombres de carpeta y / o archivo. Idealmente, primero dividiría ("/") su ruta completa y luego comprobaría las piezas. Y, obviamente, en lugar de una unión, puede agregar el carácter "%" a la lista de caracteres no permitidos en Windows, pero creo que es más útil / legible / real de esta manera. Decode () es exactamente el mismo pero cambia el Reemplazar (Uri.HexEscape (s [0]), s) "escapado" con el carácter.

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;
    }

¡Gracias @ simon-tewsi por la muy útil tabla de arriba!

m1m1k
fuente
también útil: Path.GetInvalidFileNameChars()
m1m1k
si. Aquí hay una forma de hacerlo: foreach (char c en System.IO.Path.GetInvalidFileNameChars ()) {filename = filename.Replace (c, '_'); }
netfed
0

Además de la respuesta de @Dan Herbert, generalmente deberíamos codificar solo los valores.

Split tiene el parámetro params Split ('&', '='); expresión dividida en primer lugar entre & luego '=' para que los elementos impares sean todos los valores que se codificarán a continuación.

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
fuente