Se dovessi occuparmi solo della codifica degli URL, dovrei usare EscapeUriString ?
Se dovessi occuparmi solo della codifica degli URL, dovrei usare EscapeUriString ?
Risposte:
Usa EscapeDataStringsempre (per maggiori informazioni sul perché, vedi la risposta di Livven di seguito)
Modifica : rimosso il link morto su come i due differiscono nella codifica
URLEncodeanche con ).
Non ho trovato soddisfacenti le risposte esistenti, quindi ho deciso di scavare un po 'più a fondo per risolvere il problema. Sorprendentemente, la risposta è molto semplice:
Non c'è (quasi *) alcun motivo valido per usarlo mai Uri.EscapeUriString. Se è necessario codificare in percentuale una stringa, utilizzare sempre Uri.EscapeDataString.
* Vedi l'ultimo paragrafo per un caso d'uso valido.
Perchè è questo? Secondo la documentazione :
Utilizzare il metodo EscapeUriString per preparare una stringa URI senza escape per essere un parametro per il costruttore Uri.
Questo non ha davvero senso. Secondo RFC 2396 :
Un URI è sempre in una forma di "escape", poiché l'escape o l'escaping di un URI completato potrebbe modificarne la semantica.
Mentre il RFC citato è stato superato da RFC 3986 , il punto è ancora valido. Verifichiamolo guardando alcuni esempi concreti:
Hai un URI semplice, come questo:
http://example.org/
Uri.EscapeUriString non lo cambierà.
Decidi di modificare manualmente la stringa di query senza considerare l'escaping:
http://example.org/?key=two words
Uri.EscapeUriString sfuggirà (correttamente) allo spazio per te:
http://example.org/?key=two%20wordsDecidi di modificare ulteriormente manualmente la stringa di query:
http://example.org/?parameter=father&son
Tuttavia, questa stringa non viene modificata da Uri.EscapeUriString, poiché presuppone che la e commerciale significhi l'inizio di un'altra coppia chiave-valore. Questo può o meno essere quello che volevi.
Decidi di voler effettivamente essere il keyparametro father&son, quindi correggi manualmente l'URL precedente sfuggendo alla e commerciale:
http://example.org/?parameter=father%26son
Tuttavia, Uri.EscapeUriStringsfuggirà anche al carattere percentuale, portando a una doppia codifica:
http://example.org/?parameter=father%2526sonCome puoi vedere, l'uso Uri.EscapeUriStringper lo scopo previsto rende impossibile l'utilizzo &come parte di una chiave o valore in una stringa di query anziché come separatore tra più coppie chiave-valore.
Questo perché, nel tentativo di renderlo adatto alla fuga di URI completi, ignora i caratteri riservati e sfugge solo ai caratteri che non sono né riservati né senza riserve, il che, a proposito, è contrario alla documentazione . In questo modo non si finisce con qualcosa del generehttp%3A%2F%2Fexample.org%2F , ma si finisce con i problemi illustrati sopra.
Alla fine, se l'URI è valido, non è necessario eseguirne l'escaping per passare come parametro al costruttore Uri e, se non è valido, chiamare Uri.EscapeUriString non è una soluzione magica. In realtà, funzionerà in molti, se non nella maggior parte dei casi, ma non è affatto affidabile.
Dovresti sempre costruire i tuoi URL e stringhe di query raccogliendo le coppie chiave-valore e la codifica percentuale e concatenandole con i separatori necessari. È possibile utilizzare Uri.EscapeDataStringper questo scopo, ma non Uri.EscapeUriString, poiché non sfugge ai caratteri riservati, come menzionato sopra.
Solo se non puoi farlo, ad es. Quando hai a che fare con URI forniti dagli utenti, ha senso usarlo Uri.EscapeUriStringcome ultima risorsa. Ma si applicano le avvertenze menzionate in precedenza: se l'URI fornito dall'utente è ambiguo, i risultati potrebbero non essere desiderabili.
encodeURI/ Uri.EscapeUriStringnon è necessario con la stessa frequenza di ( encodeURIComponent/ Uri.EscapeDataStringda quando stai cantando con url ciechi che devono essere usati in un contesto uri), ma ciò non significa che non abbia il suo posto.
I caratteri più (+) possono rivelare molto sulla differenza tra questi metodi. In un semplice URI, il carattere più significa "spazio". Valuta la possibilità di richiedere a Google "gatto felice":
È un URI valido (provalo) e EscapeUriStringnon lo modificherà.
Ora considera di interrogare Google per "happy c ++":
È un URI valido (provalo), ma produce una ricerca di "c felice", perché i due vantaggi sono interpretati come spazi. Per risolvere il problema, possiamo passare "happy c ++" a EscapeDataStringe voilà * :
*) La stringa di dati codificata è in realtà "happy% 20c% 2B% 2B"; % 20 è esadecimale per il carattere spazio e% 2B è esadecimale per il carattere più.
Se stai usando UriBuildercome dovresti, dovrai solo EscapeDataStringsfuggire correttamente ad alcuni dei componenti dell'intero URI. La risposta di @ Livven a questa domanda dimostra ulteriormente che non c'è davvero alcun motivo per usare EscapeUriString.
"https://www.google.com/?q=happy c++". Sembra che debba dividere manualmente "?" O c'è un modo migliore?
EscapeDataString. Se l'URL che hai fornito è l'URL effettivo, quindi sì, vuoi semplicemente dividere ?.
I commenti nella fonte affrontano chiaramente la differenza. Perché queste informazioni non vengano portate avanti tramite i commenti sulla documentazione XML è un mistero per me.
EscapeUriString:
Questo metodo sfuggirà a qualsiasi carattere che non sia un carattere riservato o senza prenotazione, inclusi i segni di percentuale. Si noti che anche EscapeUriString non sfuggirà a un segno '#'.
EscapeDataString:
Questo metodo sfuggirà a qualsiasi personaggio che non sia un personaggio senza prenotazione, inclusi i segni di percentuale.
Quindi la differenza sta nel modo in cui gestiscono i caratteri riservati . EscapeDataStringli sfugge; EscapeUriStringnon.
Secondo la RFC , i caratteri riservati sono::/?#[]@!$&'()*+,;=
Per completezza, i caratteri senza prenotazione sono alfanumerici e -._~
Entrambi i metodi sfuggono ai caratteri che non sono né riservati né senza prenotazione.
Non sono d'accordo con l' idea generale che EscapeUriStringè malvagia. Penso che sia utile un metodo che sfugga solo ai personaggi illegali (come gli spazi) e ai caratteri non riservati . Ma ha una stranezza nel modo in cui gestisce il %personaggio. I caratteri con codifica percentuale ( %seguiti da 2 cifre esadecimali) sono legali in un URI. Penso che EscapeUriStringsarebbe molto più utile se rilevasse questo schema ed evitasse la codifica %quando è immediatamente seguito da 2 cifre esadecimali.
Un semplice esempio
var data = "example.com/abc?DEF=あいう\x20えお";
Console.WriteLine(Uri.EscapeUriString(data));
Console.WriteLine(Uri.EscapeDataString(data));
Console.WriteLine(System.Net.WebUtility.UrlEncode(data));
Console.WriteLine(System.Web.HttpUtility.UrlEncode(data));
/*
=>
example.com/abc?DEF=%E3%81%82%E3%81%84%E3%81%86%20%E3%81%88%E3%81%8A
example.com%2Fabc%3FDEF%3D%E3%81%82%E3%81%84%E3%81%86%20%E3%81%88%E3%81%8A
example.com%2Fabc%3FDEF%3D%E3%81%82%E3%81%84%E3%81%86+%E3%81%88%E3%81%8A
example.com%2fabc%3fDEF%3d%e3%81%82%e3%81%84%e3%81%86+%e3%81%88%e3%81%8a
*/
Uri.EscapeDataString(), come spiegato nella risposta di @ Livven. Con altri approcci, il sistema semplicemente non ha abbastanza informazioni per produrre il risultato previsto per ogni possibile input.