Come si UrlEncode senza utilizzare System.Web?


310

Sto cercando di scrivere un'applicazione client Windows che chiama un sito Web per i dati. Per ridurre al minimo l'installazione, sto provando a utilizzare solo le dll nel profilo client di .NET Framework . Il problema è che ho bisogno di UrlEncode alcuni parametri, c'è un modo semplice per farlo senza importare System.Web.dll che non fa parte del Client Pofile?


Potresti mostrare come stai eseguendo la chiamata al sito Web? Forse c'è qualcosa che può essere fatto lì.
Darin Dimitrov,

Per curiosità, come si chiama un sito Web per i dati senza utilizzare System.Web?
Patrick McDonald,

@Patrick, probabilmente sta usando WebRequesto WebClient. Questo è il motivo per cui ho chiesto questo particolare codice perché ci sono cose che si possono fare per urlare correttamente i dati di codifica.
Darin Dimitrov,

1
Sto usando un oggetto System.Net.WebRequest. Quindi chiamo GetRequestStream e scrivo i miei parametri Post nello stream. Ho anche impostato ContentType su "application / x-www-form-urlencoded".
Martin Brown,

1
Naturalmente questo si applicherebbe altrettanto bene se stavo eseguendo una richiesta GET e aggiungendo i parametri all'URL.
Martin Brown,

Risposte:


317

System.Uri.EscapeUriString() può essere problematico con alcuni caratteri, per me era un segno numero / libbra '#' nella stringa.

Se questo è un problema per te, prova:

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

Ecco una risposta alla domanda SO che spiega la differenza:

Qual è la differenza tra EscapeUriString e EscapeDataString?

e consiglia di utilizzare Uri.EscapeDataString()in qualsiasi aspetto.


1
Falso: blogs.msdn.com/b/yangxind/archive/2006/11/09/… Avrai problemi con i segni più in quanto non saranno codificati.
Chris Weber,

7
Quel post sul blog è un po 'vecchio e ho appena "Uri Escaped" un URL completo e tutti gli spazi sono diventati% 20, quindi penso che lo abbiano risolto. Sto usando .Net 4.5.
Rodi,

Inoltre, EscapeDataString non supporta stringhe molto lunghe se si stanno preparando dati per un'operazione POST. stackoverflow.com/questions/6695208/…
Bron Davies

Uri.EscapeUriStringè davvero molto problematico e non dovrebbe essere usato, in quanto cerca di fare qualcosa (sfuggendo agli URI completi) che è effettivamente impossibile da fare in modo coerente Vedi questa risposta per una spiegazione dettagliata.
Livven,

Anche un personaggio spaziale.
Waqas Shabbir,

252

In uso .Net 4.5+ WebUtility

Solo per la formattazione, lo sto inviando come risposta.

Non sono stati trovati esempi validi confrontandoli così:

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

Uscite:

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

In uso .Net 4.5+ WebUtility.UrlEncode

Questo sembra replicare HttpUtility.UrlEncode(pre-v4.0) per i caratteri più comuni:
Uri.EscapeDataString(testString).Replace("%20", "+").Replace("'", "%27").Replace("~", "%7E")
Nota: EscapeUriStringmanterrà una stringa uri valida, che lo farà usare il maggior numero possibile di caratteri in chiaro.

Vedi questa risposta per una tabella che confronta le varie codifiche:
https://stackoverflow.com/a/11236038/555798

Interruzioni di riga Tutti elencati qui (diversi da HttpUtility.HtmlEncode) verranno convertiti "\n\r"in %0a%0do%0A%0D

Non esitate a modificare questo e aggiungere nuovi caratteri alla mia stringa di prova, oppure lasciarli nei commenti e lo modificherò.


Nel mio caso ho dovuto usare EscapeDataStringpiuttosto che EscapeUriStringcodificare i ritorni a capo e i feed di riga e questi richiedevano la fuga più aggressiva eseguita daEscapeDataString
David O'Meara il

1
altri esempi, se lo desideri puoi fornire i tuoi casi di test. Ecco un esempio di esecuzione e gli altri metodi di codifica che mostrano le differenze dotnetfiddle.net/12IFw1
Maslow,

3
WebUtility.UrlEncode () e WebUtility.UrlDecode () sono 4.5+. Non esistono in 4.0.
Derek Kalweit,

Il msdn dice: "Universal Windows Platform: disponibile da 4.5, .NET Framework: disponibile da 4.0" ...
Thymine,

54

C'è una differenza tra questo e EscapeDataString?
Martin Brown,

3
Vuoi usare EscapeUriString. EscapeUriString proverà a codificare l'intero URL (includi http: // parte) mentre EscapeUriString comprende quali parti effettivamente devono essere codificate
Matthew Manela,

1
Vedo, quindi in questo caso probabilmente vorrei EscapeDataString in quanto potrei voler passare un URL come parametro get. In questo caso aggiungo un URL.
Martin Brown,

5
@MatthewManela Sono abbastanza sicuro che il tuo commento Ott1 dovrebbe leggere The EscapeDataString proverà a codificare ...
Maslow

Non usare Uri.EscapeUriString. Non "capisce" quali parti devono essere codificate, è solo un tentativo fuorviato di fare qualcosa (sfuggire agli URI completi) che è effettivamente impossibile fare in modo coerente. Vedi questa risposta per una spiegazione dettagliata.
Livven,

20

Le risposte qui sono molto buone, ma ancora insufficienti per me.

Ho scritto un piccolo ciclo che si confronta Uri.EscapeUriStringcon Uri.EscapeDataStringper tutti i personaggi da 0 a 255.

NOTA: Entrambe le funzioni hanno l'intelligenza integrata che i caratteri sopra 0x80 sono prima codificati UTF-8 e poi codificati in percentuale.

Ecco il risultato:

******* 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"
.....

EscapeUriStringdeve essere utilizzato per codificare gli URL, mentre EscapeDataStringdeve essere utilizzato per codificare, ad esempio, il contenuto di un cookie, poiché i dati del cookie non devono contenere i caratteri riservati '='e ';'.


bella analisi e ripartizione qui, molto utile. se qualcuno ha o conosce benchmark di prestazione (confrontando tutti e tre i metodi) che sarebbe anche bello vedere
Shaun Wilson

Questa è una buona analisi e il takeaway è che non dovresti usarlo Uri.EscapeUriString, perché è impossibile eseguire coerentemente la fuga di URI completi. Vedi questa risposta per una spiegazione dettagliata.
Livven,

16

Esiste una versione utilizzabile del profilo client, classe System.Net.WebUtility, presente nel profilo client System.dll. Ecco il collegamento MSDN:

WebUtility


Noterei che la pagina di aiuto per quella classe dice specificamente "Fornisce metodi per codificare e decodificare gli URL durante l'elaborazione delle richieste Web." quindi potrebbe essere solo che non abbiano nominato bene i metodi.
James White,

Buon punto, diciamo, perché non voti un fratello in alto;) questo voto in basso mi perseguita da 2 anni! JK ... ma onestamente è probabilmente per questo che ho pubblicato il link, sfortunato che mi prenda un colpo di reputazione per errori nei documenti di Microsoft ...
Sprague,

11
Sembra che UrlEncode e UrlDecode siano stati aggiunti a WebUtility solo nella versione 4.5 di .Net.
Martin Brown,

8

Ecco un esempio di invio di una richiesta POST che codifica correttamente i parametri utilizzando il application/x-www-form-urlencodedtipo di contenuto:

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


-3
System.Net.WebUtility.HtmlDecode

La classe WebUtility fornisce metodi per codificare e decodificare gli URL durante l'elaborazione delle richieste Web. Fa la stessa cosa di HttpUtility ma è fuori dallo spazio dei nomi System.Web
Alexandru Aliu,

3
È sbagliato perché HtmlDecodes e non UrlEncode come la domanda posta. Anche HtmlEncode sarebbe sbagliato in quanto la codifica HTML è diversa dalla codifica URL.
Martin Brown,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.