without httputility .net urlencode

.net - httputility - url encode



¿Cuál es la diferencia entre EscapeUriString y EscapeDataString? (4)

Si solo trato con la codificación de URL, debería usar EscapeUriString ?


Los caracteres más (+) pueden revelar mucho sobre la diferencia entre estos métodos. En un URI simple, el carácter más significa "espacio". Considera consultar a Google por "gato feliz":

https://www.google.com/?q=happy+cat

Es un URI válido (pruébalo), y EscapeUriString no lo modificará.

Ahora considere consultar a Google por "happy c ++":

https://www.google.com/?q=happy+c++

Es un URI válido (pruébelo), pero produce una búsqueda de "c feliz", porque las dos ventajas se interpretan como espacios. Para solucionarlo, podemos pasar "happy c ++" a EscapeDataString y voila * :

https://www.google.com/?q=happy+c%2B%2B

*) La cadena de datos codificados es en realidad "feliz% 20c% 2B% 2B"; % 20 es hex para el carácter de espacio, y% 2B es hex para el carácter de más.

Si está utilizando UriBuilder como debería, entonces solo necesitará EscapeDataString para escapar correctamente de algunos de los componentes de su URI completo. La respuesta de @ Livven a esta pregunta prueba que realmente no hay ninguna razón para usar EscapeUriString .


Los comentarios en la source abordan la diferencia claramente. Por qué esta información no se presenta a través de los comentarios de la documentación XML es un misterio para mí.

EscapeUriString:

Este método escapará a cualquier carácter que no sea un carácter reservado o sin reserva, incluidos los signos de porcentaje. Tenga en cuenta que EscapeUriString tampoco escapará a un signo ''#''.

EscapeDataString:

Este método escapará a cualquier carácter que no sea un carácter no reservado, incluidos los signos de porcentaje.

Entonces, la diferencia radica en cómo manejan los caracteres reservados . EscapeDataString se les escapa; EscapeUriString no.

De acuerdo con el RFC , los caracteres reservados son:: :/?#[]@!$&''()*+,;=

Para completar, los caracteres sin reserva son alfanuméricos y -._~

Ambos métodos escapan de los caracteres que no están reservados ni no reservados.

No estoy de acuerdo con la notion general de que EscapeUriString es malo. Creo que un método que solo escapa a caracteres ilegales (como espacios) y no a caracteres reservados es útil. Pero tiene una peculiaridad en la forma en que maneja el carácter % . Los caracteres porcentuales codificados ( % seguidos de 2 dígitos hexadecimales) son legales en un URI. Creo que EscapeUriString sería mucho más útil si detectara este patrón y evitara el % codificación cuando proceda inmediatamente con 2 dígitos hexadecimales.


No encontré las respuestas existentes satisfactorias, así que decidí profundizar un poco más para resolver este problema. Sorprendentemente, la respuesta es muy simple:

No hay una razón válida para usar Uri.EscapeUriString . Si necesita codificar porcentualmente una cadena, siempre use Uri.EscapeDataString .

¿Por qué es esto? De acuerdo con la documentation :

Utilice el método EscapeUriString para preparar una cadena de URI sin guardar como un parámetro para el constructor de Uri.

Esto realmente no tiene sentido. De acuerdo con RFC 2396 :

Un URI siempre está en una forma "escapada", ya que al escaparse o desacralizar un URI completo podría cambiar su semántica.

Mientras que el RFC citado ha sido obsoleto por RFC 3986 , el punto sigue en pie. Vamos a verificarlo mirando algunos ejemplos concretos:

  1. Tienes un URI simple, como este:

    http://example.org/

    Uri.EscapeUriString no lo cambiará.

  2. Decide editar manualmente la cadena de consulta sin tener en cuenta el escape:

    http://example.org/?key=two words

    Uri.EscapeUriString (correctamente) del espacio por usted:

    http://example.org/?key=two%20words

  3. Decide editar manualmente la cadena de consulta aún más:

    http://example.org/?parameter=father&son

    Sin embargo, Uri.EscapeUriString no cambia esta cadena, ya que supone que el signo & significa el inicio de otro par de clave-valor. Esto puede o no ser lo que pretendías.

  4. Usted decide que de hecho desea que el parámetro key sea father&son , por lo que arregla la URL anterior manualmente escapando del signo y:

    http://example.org/?parameter=father%26son

    Sin embargo, Uri.EscapeUriString también escapará del carácter de porcentaje, lo que Uri.EscapeUriString una doble codificación:

    http://example.org/?parameter=father%2526son

Como puede ver, el uso de Uri.EscapeUriString para su propósito previsto hace que sea imposible usar & como parte de una clave o valor en una cadena de consulta en lugar de como un separador entre múltiples pares clave-valor.

Esto se debe a que, en un intento equivocado de hacerlo adecuado para escapar de URI completos, ignora los caracteres reservados y solo escapa de los caracteres que no son ni reservados ni sin reservas, lo que, por cierto, es contrario a la documentation . De esta manera no terminas con algo como http%3A%2F%2Fexample.org%2F , pero terminas con los problemas ilustrados arriba.

Al final, si su URI es válido, no necesita ser escapado para pasarlo como un parámetro al construtor de Uri, y si no es válido, entonces llamar a Uri.EscapeUriString tampoco es una solución mágica. En realidad, funcionará en muchos casos, si no en la mayoría, pero de ninguna manera es confiable.

Siempre debe construir sus URL y cadenas de consulta reuniendo los pares clave-valor y la codificación porcentual y luego concatenándolos con los separadores necesarios. Puede usar Uri.EscapeDataString para este propósito, pero no para Uri.EscapeUriString , ya que no escapa de los caracteres reservados, como se mencionó anteriormente.