2010-10-01 15 views
256

Estoy tratando de escribir una aplicación de cliente de Windows que llama a un sitio web para obtener datos. Para mantener la instalación al mínimo, solo intento usar dlls in the .NET Framework Client Profile. El problema es que necesito UrlEncode algunos parámetros, ¿hay una manera fácil de hacerlo sin importar System.Web.dll que no es parte de Client Pofile?¿Cómo hace UrlEncode sin usar System.Web?

+0

Podría mostrar cómo estás realizando la llamada al sitio web? Tal vez hay algo que se puede hacer allí. –

+0

Por curiosidad, ¿cómo llama a un sitio web para obtener datos sin usar System.Web? –

+0

@Patrick, probablemente esté usando 'WebRequest' o' WebClient'. Esa es la razón por la que pregunté acerca de este código en particular porque hay cosas que se pueden hacer sobre los datos de codificación de url correctamente. –

Respuesta

246

System.Uri.EscapeUriString() puede ser problemático con ciertos caracteres, para mí fue un signo de número/libra '#' en la cadena.

Si esto es un problema para usted, trate de:

System.Uri.EscapeDataString() //Works excellent with individual values 

Aquí está una pregunta para respuesta que explica la diferencia:

What's the difference between EscapeUriString and EscapeDataString?

y recomienda utilizar Uri.EscapeDataString() en cualquier aspecto.

+1

False: http://blogs.msdn.com/b/yangxind/archive/2006/11/09/don-t-use-net-system-uri-unescapedatastring-in-url-decoding.aspx Tendrás problemas con los signos más ya que no estarán sin codificar. –

+5

Esa publicación del blog es un poco antigua y solo tengo "Uri Escaped" una url completa y todos los espacios se han convertido en% 20, así que creo que lo arreglaron. Estoy usando .Net 4.5. – Rodi

+0

EscapeDataString tampoco admite cadenas muy largas si está preparando datos para una operación POST. http://stackoverflow.com/questions/6695208/uri-escapedatastring-invalid-uri-the-uri-string-is-too-long –

15

Hay una versión utilizable del perfil de cliente, clase System.Net.WebUtility, presente en el perfil del cliente System.dll. Aquí está la MSDN Enlace:

WebUtility

+0

Desafortunadamente, no existe el método 'UrlEncode' allí. –

+0

ahh bien, fallar para mí = (¿Alguna vez ha revisado una sola pregunta de desbordamiento de pila? – Sprague

+1

solo las que me interesan. –

50
+0

¿Hay alguna diferencia entre esto y EscapeDataString? –

+3

Desea utilizar EscapeUriString.El EscapeUriString intentará codificar toda la url (incluye http: // parte) mientras que EscapeUriString entiende qué partes realmente deberían codificarse –

+1

Veo, así que en este caso, probablemente desearía EscapeDataString, ya que podría querer pasar una URL como un get parámetro. Estoy agregando una URL en esta instancia. –

8

He aquí un ejemplo de enviar una solicitud POST que codifica correctamente los parámetros utilizando el tipo application/x-www-form-urlencoded contenido:

using (var client = new WebClient()) 
{ 
    var values = new NameValueCollection 
    { 
     { "param1", "value1" }, 
     { "param2", "value2" }, 
    }; 
    var result = client.UploadValues("http://foo.com", values); 
} 
186

En .Net 4.5+ usar WebUtility

Sólo para el formato que estoy presentando esto como una respuesta.

No se pudo encontrar ningún buenos ejemplos comparándolos así:

string testString = "http://test# space 123/text?var=val&another=two"; 
Console.WriteLine("UrlEncode:   " + System.Web.HttpUtility.UrlEncode(testString)); 
Console.WriteLine("EscapeUriString: " + Uri.EscapeUriString(testString)); 
Console.WriteLine("EscapeDataString: " + Uri.EscapeDataString(testString)); 
Console.WriteLine("EscapeDataReplace: " + Uri.EscapeDataString(testString).Replace("%20", "+")); 

Console.WriteLine("HtmlEncode:  " + System.Web.HttpUtility.HtmlEncode(testString)); 
Console.WriteLine("UrlPathEncode:  " + System.Web.HttpUtility.UrlPathEncode(testString)); 

//.Net 4.0+ 
Console.WriteLine("WebUtility.HtmlEncode: " + WebUtility.HtmlEncode(testString)); 
//.Net 4.5+ 
Console.WriteLine("WebUtility.UrlEncode: " + WebUtility.UrlEncode(testString)); 

Salidas:

UrlEncode:   http%3a%2f%2ftest%23+space+123%2ftext%3fvar%3dval%26another%3dtwo 
EscapeUriString: http://test#%20space%20123/text?var=val&another=two 
EscapeDataString: http%3A%2F%2Ftest%23%20space%20123%2Ftext%3Fvar%3Dval%26another%3Dtwo 
EscapeDataReplace: http%3A%2F%2Ftest%23+space+123%2Ftext%3Fvar%3Dval%26another%3Dtwo 

HtmlEncode:  http://test# space 123/text?var=val&another=two 
UrlPathEncode:  http://test#%20space%20123/text?var=val&another=two 

//.Net 4.0+ 
WebUtility.HtmlEncode: http://test# space 123/text?var=val&another=two 
//.Net 4.5+ 
WebUtility.UrlEncode: http%3A%2F%2Ftest%23+space+123%2Ftext%3Fvar%3Dval%26another%3Dtwo 

En .Net 4.5+ usar WebUtility.UrlEncode

Esto parece replicar HttpUtility.UrlEncode (pre -v4.0) para los caracteres más comunes:
Uri.EscapeDataString(testString).Replace("%20", "+").Replace("'", "%27").Replace("~", "%7E")
Nota: EscapeUriString mantendrá una cadena uri válida, lo que provoca que use tantos caracteres de texto sin cifrar como sea posible.

Ver esta respuesta para un cuadro comparativo de las diferentes codificaciones:
https://stackoverflow.com/a/11236038/555798

saltos de línea Todos ellos figuran en esta lista (que no sea HttpUtility.HtmlEncode) convertirá "\n\r" en %0a%0d o %0A%0D

favor siéntete libre de editar esto y agregar nuevos caracteres a mi cadena de prueba, o dejarlos en los comentarios y lo editaré.

+0

En mi caso tuve que usar 'EscapeDataString' en lugar de' EscapeUriString' ya que codificamos retornos de carro y alimentaciones de línea y estos requerían el escape más agresivo realizado por 'EscapeDataString' –

+1

más ejemplos, puede proporcionar sus propios casos de prueba si querer. Aquí hay una muestra de cómo ejecutarlo y los otros métodos de codificación que muestran las diferencias https://dotnetfiddle.net/12IFw1 – Maslow

+3

WebUtility.UrlEncode() y WebUtility.UrlDecode() son 4.5+. No existen en 4.0. –

-2
System.Net.WebUtility.HtmlDecode 
+0

¡Esta respuesta es incorrecta! – Elmue

+0

¿Por qué está mal? –

+0

La clase WebUtility proporciona métodos para codificar y decodificar URL al procesar solicitudes web. Hace lo mismo que HttpUtility pero está fuera del espacio de nombres System.Web –

16

Las respuestas aquí son muy buenas, pero aún son insuficientes para mí.

me escribió un pequeño bucle que se compara con Uri.EscapeUriStringUri.EscapeDataString para todos los caracteres del 0 al 255.

NOTA: Ambas funciones tienen la inteligencia integrada que los caracteres anteriores son 0x80 primera codificación UTF-8 y luego por ciento codificada .

Este es el resultado:

******* Different ******* 

'#' -> Uri "#" Data "%23" 
'$' -> Uri "$" Data "%24" 
'&' -> Uri "&" Data "%26" 
'+' -> Uri "+" Data "%2B" 
',' -> Uri "," Data "%2C" 
'/' -> Uri "/" Data "%2F" 
':' -> Uri ":" Data "%3A" 
';' -> Uri ";" Data "%3B" 
'=' -> Uri "=" Data "%3D" 
'?' -> Uri "?" Data "%3F" 
'@' -> Uri "@" Data "%40" 


******* Not escaped ******* 

'!' -> Uri "!" Data "!" 
''' -> Uri "'" Data "'" 
'(' -> Uri "(" Data "(" 
')' -> Uri ")" Data ")" 
'*' -> Uri "*" Data "*" 
'-' -> Uri "-" Data "-" 
'.' -> Uri "." Data "." 
'_' -> Uri "_" Data "_" 
'~' -> Uri "~" Data "~" 

'0' -> Uri "0" Data "0" 
..... 
'9' -> Uri "9" Data "9" 

'A' -> Uri "A" Data "A" 
...... 
'Z' -> Uri "Z" Data "Z" 

'a' -> Uri "a" Data "a" 
..... 
'z' -> Uri "z" Data "z" 

******* UTF 8 ******* 

..... 
'Ò' -> Uri "%C3%92" Data "%C3%92" 
'Ó' -> Uri "%C3%93" Data "%C3%93" 
'Ô' -> Uri "%C3%94" Data "%C3%94" 
'Õ' -> Uri "%C3%95" Data "%C3%95" 
'Ö' -> Uri "%C3%96" Data "%C3%96" 
..... 

EscapeUriString se va a utilizar para codificar URLs, mientras EscapeDataString es para ser utilizado para codificar, por ejemplo, el contenido de una galleta, porque los datos de cookies no deben contener los caracteres reservados '=' y ';'.

+0

buen análisis y desglose aquí, muy útil. si alguien tiene o conoce puntos de referencia de rendimiento (comparando los tres métodos) que también sería bueno ver –

+0

Este es un buen análisis y la conclusión es que no debe usar 'Uri.EscapeUriString', porque es imposible escaparse de los URI completos hacer consistentemente. Ver [esta respuesta] (http://stackoverflow.com/a/34189188/1488656) para una explicación detallada. – Livven

Cuestiones relacionadas