Si je ne m'occupe que de l'encodage des urls, je devrais utiliser EscapeUriString ?
Wow, merci d'avoir enfin clarifié cette question. Les deux réponses précédentes n'étaient pas très utiles.
Si je ne m'occupe que de l'encodage des urls, je devrais utiliser EscapeUriString ?
Les réponses existantes ne me satisfaisant pas, j'ai décidé de creuser un peu plus pour régler cette question. Étonnamment, la réponse est très simple :
_Il y a (presque ) aucune raison valable de ne jamais utiliser Uri.EscapeUriString
. Si vous avez besoin de coder en pourcentage une chaîne de caractères, utilisez toujours Uri.EscapeDataString
._ *
* Voir le dernier paragraphe pour un cas d'utilisation valide.
Pourquoi ? Selon le documentation :
Utilisez la méthode EscapeUriString pour préparer une chaîne URI non encodée qui servira de paramètre au constructeur d'Uri.
Cela n'a pas vraiment de sens. D'après RFC 2396 :
Un URI est toujours sous une forme "échappée", car l'échappement ou le dés échappement d'un URI complet peut modifier sa sémantique.
Alors que la RFC citée a été rendue obsolète par RFC 3986 le point est toujours d'actualité. Vérifions-le en examinant quelques exemples concrets :
Vous avez un simple URI, comme ceci :
http://example.org/
Uri.EscapeUriString
ne le changera pas.
Vous décidez de modifier manuellement la chaîne de requête sans tenir compte de l'échappement :
http://example.org/?key=two words
Uri.EscapeUriString
s'échappera (correctement) de l'espace pour vous :
http://example.org/?key=two%20words
Vous décidez de modifier manuellement la chaîne de requête encore plus loin :
http://example.org/?parameter=father&son
Cependant, cette chaîne n'est pas modifiée par Uri.EscapeUriString
car il suppose que l'esperluette signifie le début d'une autre paire clé-valeur. Cela peut être ou ne pas être ce que vous vouliez.
Vous décidez que vous voulez en fait le key
à être father&son
Vous devez donc corriger manuellement l'URL précédente en échappant l'esperluette :
http://example.org/?parameter=father%26son
Cependant, Uri.EscapeUriString
échappe également le caractère pour cent, ce qui entraîne un double encodage :
http://example.org/?parameter=father%2526son
Comme vous pouvez le constater, l'utilisation de Uri.EscapeUriString
pour l'usage auquel il est destiné rend impossible l'utilisation &
comme partie d'une clé ou d'une valeur dans une chaîne de requête, plutôt que comme séparateur entre plusieurs paires clé-valeur.
Ceci est dû au fait que, dans une tentative de le rendre adapté à l'échappement des URI complets, il ignore les caractères réservés et n'échappe que les caractères qui ne sont ni réservés ni non réservés, ce qui, entre parenthèses, est contraire à la directive documentation . De cette façon, vous ne vous retrouvez pas avec quelque chose comme http%3A%2F%2Fexample.org%2F
mais vous vous retrouvez avec les problèmes illustrés ci-dessus.
Au final, si votre URI est valide, il n'a pas besoin d'être échappé pour être passé en paramètre au constructeur d'Uri, et s'il n'est pas valide, alors appeler Uri.EscapeUriString
n'est pas non plus une solution magique. En fait, elle fonctionnera dans de nombreux cas, sinon dans la plupart, mais elle n'est en aucun cas fiable.
Vous devez toujours construire vos URL et chaînes de requête en rassemblant les paires clé-valeur et le codage en pourcentage, puis en les concaténant avec les séparateurs nécessaires. Vous pouvez utiliser Uri.EscapeDataString
à cette fin, mais pas Uri.EscapeUriString
car il n'échappe pas les caractères réservés, comme mentionné ci-dessus.
Ce n'est que si vous ne pouvez pas le faire, par exemple lorsque vous traitez des URI fournis par l'utilisateur, qu'il est judicieux d'utiliser Uri.EscapeUriString
en dernier recours. Mais les mises en garde mentionnées précédemment s'appliquent - si l'URI fournie par l'utilisateur est ambiguë, les résultats peuvent ne pas être souhaitables.
Wow, merci d'avoir enfin clarifié cette question. Les deux réponses précédentes n'étaient pas très utiles.
C'est tout à fait exact. EscapeUriString (comme le comportement par défaut de EscapeUrl dans Win32) a été créé par quelqu'un qui ne comprenait pas les URI ou l'échappement. C'est une tentative malavisée de créer quelque chose qui prend un URI malformé et qui parfois le transformer en la version prévue. Mais il ne dispose pas des informations nécessaires pour le faire de manière fiable. Il est aussi fréquemment utilisé à la place de EscapeDataString, ce qui est également très problématique. J'aimerais que EscapeUriString n'existe pas. Chaque utilisation est erronée.
Utilisez EscapeDataString
toujours (pour plus d'informations sur la raison, voir La réponse de Livven ci-dessous)
Modifier : suppression d'un lien mort vers la différence entre les deux sur l'encodage
Je ne suis pas sûr que ce lien apporte plus d'informations car il concerne l'unscaping plutôt que l'esacaping.
C'est à peu près la même différence. Si vous lisez vraiment l'article, vous verrez qu'il y a un tableau au milieu de l'article qui montre les différences (en comparant avec URLEncode
aussi).
Ce n'est toujours pas clair pour moi : que se passe-t-il si je n'échappe pas un URI entier mais seulement une partie de celui-ci (c'est-à-dire le nom de l'utilisateur) ? données pour un paramètre de chaîne de requête) ? Suis-je en train d'échapper des données pour l'URI, ou EscapeDataString implique-t-il quelque chose de complètement différent ?
Les caractères plus (+) peuvent en dire long sur la différence entre ces méthodes. Dans un URI simple, le caractère plus signifie "espace". Par exemple, vous pouvez demander à Google de rechercher "chat heureux" :
C'est un URI valide (essayez-le), et EscapeUriString
ne le modifiera pas.
Maintenant, pensez à interroger Google pour "happy c++" :
C'est une URI valide (essayez-la), mais elle produit une recherche pour "happy c", parce que les deux plus sont interprétés comme des espaces. Pour corriger cela, nous pouvons passer "happy c++" à EscapeDataString
et voilà * :
*) La chaîne de données codée est en fait "happy%20c%2B%2B" ; %20 est un hexagone pour le caractère espace, et %2B est un hexagone pour le caractère plus.
Si vous utilisez UriBuilder
comme vous devriez l'être, alors vous n'aurez besoin que de EscapeDataString
pour échapper correctement à certains des composants de votre URI entier. La réponse de @Livven à cette question prouve une fois de plus qu'il n'y a vraiment aucune raison d'utiliser EscapeUriString
.
Merci. Qu'en est-il lorsque vous avez une chaîne URI absolue que vous devez encoder, par exemple "https://www.google.com/?q=happy c++"
. Il semble que je doive diviser manuellement sur " ?", ou y a-t-il une meilleure méthode ?
Commentaires dans le source aborder clairement la différence. La raison pour laquelle cette information n'est pas présentée dans les commentaires de la documentation XML est un mystère pour moi.
EscapeUriString :
Cette méthode permet d'échapper à tout caractère qui n'est ni réservé ni non réservé, y compris les pourcentages. Notez que EscapeUriString n'échappe pas non plus le signe '#'.
EscapeDataString :
Cette méthode permet d'échapper à tout caractère qui n'est pas un caractère non réservé. y compris les signes de pourcentage.
Donc la différence est dans la façon dont ils gèrent réservé des personnages. EscapeDataString
leur échappe ; EscapeUriString
ne le fait pas.
Según la RFC les caractères réservés sont : :/?#[]@!$&'()*+,;=
Pour être complet, les caractères non réservés sont alphanumériques et -._~
Les deux méthodes permettent d'échapper aux caractères qui ne sont ni réservés ni non réservés.
Je ne suis pas d'accord avec le général notion que EscapeUriString
c'est le mal. Je pense qu'une méthode qui échappe seulement illégal des caractères (tels que des espaces) et non réservé caractères est utile. Mais il y a une bizarrerie dans la façon dont il traite les caractères de l'option %
caractère. Les caractères codés en pourcentage ( %
suivi de 2 chiffres hexadécimaux) sont légal dans un URI. Je pense EscapeUriString
serait beaucoup plus utile s'il détectait ce modèle et évitait d'encoder %
lorsqu'il est immédiatement précédé de 2 chiffres hexadécimaux.
Un exemple simple
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
*/
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
11 votes
Toujours échapper à chaque individu valeur en utilisant
Uri.EscapeDataString()
comme expliqué dans la réponse de @Livven. Avec d'autres approches, le système ne dispose tout simplement pas de suffisamment d'informations pour produire le résultat escompté pour chaque entrée possible.