221 votes

Quelle est la différence entre EscapeUriString et EscapeDataString ?

Si je ne m'occupe que de l'encodage des urls, je devrais utiliser EscapeUriString ?

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.

295voto

Livven Points 546

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 :

  1. Vous avez un simple URI, comme ceci :

     http://example.org/

Uri.EscapeUriString ne le changera pas.

  1. 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
  1. 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.

  1. 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.

5 votes

Wow, merci d'avoir enfin clarifié cette question. Les deux réponses précédentes n'étaient pas très utiles.

5 votes

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.

5 votes

Bien expliqué +1 c'est bien mieux qu'une réponse acceptée uniquement par lien

127voto

Jcl Points 2120

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

3 votes

Je ne suis pas sûr que ce lien apporte plus d'informations car il concerne l'unscaping plutôt que l'esacaping.

1 votes

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

2 votes

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 ?

61voto

Seth Points 567

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" :

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

C'est un URI valide (essayez-le), et EscapeUriString ne le modifiera pas.

Maintenant, pensez à interroger Google pour "happy c++" :

https://www.google.com/?q=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à * :

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

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

0 votes

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 ?

0 votes

Si vous transmettez l'URL entière comme paramètre à une autre URL, utilisez alors EscapeDataString . Si l'URL que vous avez fournie est l'URL réelle, alors oui, vous devez simplement la diviser en deux. ? .

8voto

Todd Menier Points 3599

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.

3voto

KnowledgeSeeker Points 2546

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.com

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.

Powered by:

X