Server.UrlEncode et HttpUtility.UrlEncode

177

Existe-t-il une différence entre Server.UrlEncode et HttpUtility.UrlEncode?

Manu
la source

Réponses:

133

HttpServerUtility.UrlEncodeutilisera en HttpUtility.UrlEncodeinterne. Il n'y a pas de différence spécifique. La raison de l'existence de Server.UrlEncodeest la compatibilité avec l'ASP classique.

Mehrdad Afshari
la source
3
Quant à ce qui s'échappe. En interne, il appelle cette fonction referencesource.microsoft.com/#System/net/System/Net/...
Jeff
Pour les lecteurs: Veuillez consulter la réponse de Joel Muller ci-dessous. C'est le moyen le plus efficace d'encoder une URL: stackoverflow.com/a/603962/190476
Sudhanshu Mishra
264

J'ai eu des maux de tête importants avec ces méthodes auparavant, je vous recommande d' éviter toute variante de UrlEncode, et d'utiliser à la placeUri.EscapeDataString - au moins celle-ci a un comportement compréhensible.

Voyons voir...

HttpUtility.UrlEncode(" ") == "+" //breaks ASP.NET when used in paths, non-
                                  //standard, undocumented.
Uri.EscapeUriString("a?b=e") == "a?b=e" // makes sense, but rarely what you
                                        // want, since you still need to
                                        // escape special characters yourself

Mais mon préféré doit être HttpUtility.UrlPathEncode - cette chose est vraiment incompréhensible. Il encode:

  • "" ==> "% 20"
  • "100% true" ==> "100 %% 20true" (ok, votre URL est maintenant cassée)
  • "test A.aspx # anchor B" ==> "test% 20A.aspx # anchor% 20B "
  • "test A.aspx? hmm # anchor B" ==> "test% 20A.aspx? hmm #anchor B " ( notez la différence avec la séquence d'échappement précédente! )

Il contient également la documentation MSDN joliment spécifique «Encode la partie chemin d'une chaîne URL pour une transmission HTTP fiable du serveur Web à un client». - sans vraiment expliquer ce qu'il fait. Vous êtes moins susceptible de vous tirer une balle dans le pied avec un Uzi ...

En bref, respectez Uri.EscapeDataString .

Eamon Nerbonne
la source
4
Et malheureusement, cela ne fonctionne toujours pas lors des requêtes HTTP contre certains serveurs Web - Uri.EscapeDataString () n'encode pas "!" ou "'", qui diffère de la façon dont la plupart des implémentations de navigateur de escape () fonctionnent ...
Chris R. Donnelly
6
! et 'les caractères ne sont pas censés être encodés; mais si un serveur Web bogué l'exige, il est facile de contourner le problème. Évitez la fonction d'échappement de javascript - elle est intrinsèquement boguée (impossible d'aller-retour, par exemple). Voir xkr.us/articles/javascript/encode-compare - mais en bref; vous pouvez utiliser encodeUriComponent () à la place, qui se comporte de la même manière que EscapeDataString - il encode de manière prévisible et réversible une chaîne et n'encode pas non plus! et 'caractères.
Eamon Nerbonne
2
C'est vieux, mais la question a été renvoyée à la page d'accueil, donc .... La partie chemin d'une chaîne d'URL est la partie entre le domaine et le? ou # dans une URL.
Powerlord
2
@Tim: il peut y en avoir plusieurs ?et qui peut dire lesquels doivent être encodés et lesquels servent de séparateurs? Quant à l'espace: dans les deux cas, l'espace est dans le hachage, donc la présence ou l'absence d'un fragment de requête ne devrait pas avoir d'importance. Et enfin, il est inexcusable de corrompre un Uri comme dans le deuxième exemple contenant un%. La UrlPathEncodeméthode est simple et ne doit jamais être utilisée.
Eamon Nerbonne
1
Je pense que ma réponse à stackoverflow.com/a/13993486/237091 peut éclairer un peu l'utilisation prévue de UrlEncode / UrlPathEncode.
Scott Stafford
60

Avance rapide de près de 9 ans depuis que cela a été demandé pour la première fois, et dans le monde de .NET Core et .NET Standard, il semble que les options les plus courantes que nous ayons pour le codage d'URL soient WebUtility.UrlEncode (sous System.Net) et Uri.EscapeDataString . À en juger par la réponse la plus populaire ici et ailleurs, Uri.EscapeDataString semble être préférable. Mais est-ce vrai? J'ai fait quelques analyses pour comprendre les différences et voici ce que j'ai trouvé:

À des fins de codage d'URL, les caractères entrent dans l'une des 3 catégories suivantes: non réservés (légaux dans une URL); réservé (légal mais a une signification particulière, vous pouvez donc vouloir l'encoder); et tout le reste (doit toujours être encodé).

Selon la RFC , les caractères réservés sont::/?#[]@!$&'()*+,;=

Et les caractères non réservés sont alphanumériques et -._~

Le verdict

Uri.EscapeDataString définit clairement sa mission:% -encode tous les caractères réservés et illégaux. WebUtility.UrlEncode est plus ambigu à la fois dans sa définition et dans sa mise en œuvre. Curieusement, il encode certains caractères réservés mais pas d'autres (pourquoi des parenthèses et pas des crochets ??), et plus étrange encore, il encode ce caractère innocemment non réservé ~.

Par conséquent, je suis d'accord avec le conseil populaire: utilisez Uri.EscapeDataString lorsque cela est possible et comprenez que les caractères réservés aiment /et ?seront encodés. Si vous devez gérer des chaînes potentiellement volumineuses, en particulier avec du contenu de formulaire encodé en URL, vous devrez soit vous rabattre sur WebUtility.UrlEncode et accepter ses bizarreries, soit contourner le problème.


EDIT: J'ai tenté de rectifier TOUTES les bizarreries mentionnées ci - dessus dans Flurl par les Url.Encode, Url.EncodeIllegalCharacterset les Url.Decodeméthodes statiques. Ceux-ci sont dans le package de base (qui est minuscule et n'inclut pas tous les éléments HTTP), ou n'hésitez pas à les extraire de la source. Je suis heureux de recevoir vos commentaires / commentaires à ce sujet.


Voici le code que j'ai utilisé pour découvrir quels caractères sont encodés différemment:

var diffs =
    from i in Enumerable.Range(0, char.MaxValue + 1)
    let c = (char)i
    where !char.IsHighSurrogate(c)
    let diff = new {
        Original = c,
        UrlEncode = WebUtility.UrlEncode(c.ToString()),
        EscapeDataString = Uri.EscapeDataString(c.ToString()),
    }
    where diff.UrlEncode != diff.EscapeDataString
    select diff;

foreach (var diff in diffs)
    Console.WriteLine($"{diff.Original}\t{diff.UrlEncode}\t{diff.EscapeDataString}");
Todd Menier
la source
2
C'est génial!
Jorge Aguirre
1
Excellent travail de vérification de la solution suggérée sur le framework .net moderne.
Neowizard
Il convient de mentionner qu'il existe des différences entre WebUtility et HttpUtility . WebUtility utilise des majuscules et HttpUtility utilise des minuscules pour les entités hexa. En outre, HttpUtility n'était pas inclus dans les anciennes versions de sous-ensembles de .NET Framework «Client Profile». WebUtility est disponible à partir de .NET Framework 4.0.
tibx
28

Gardez à l'esprit que vous ne devriez probablement pas utiliser l'une de ces méthodes. La bibliothèque de scripts anti-intersite de Microsoft comprend des remplacements pour HttpUtility.UrlEncodeet HttpUtility.HtmlEncodequi sont à la fois plus conformes aux normes et plus sécurisés. En prime, vous bénéficiez également d'une JavaScriptEncodeméthode.

Joel Mueller
la source
Après avoir lu la documentation et la FAQ sur le lien fourni, je pense que cette réponse est le moyen le meilleur et le plus sûr d'encoder des données! Merci beaucoup d'avoir partagé ça!
Sudhanshu Mishra
Le lien ne fonctionne plus. Quelles sont les méthodes de remplacement?
Edward Brey
@EdwardBrey Ceci est la dernière version de la bibliothèque de scripts de site Anti-Cross: microsoft.com/en-au/download/details.aspx?id=28589
Sudhanshu Mishra
11

Server.UrlEncode () est là pour fournir une compatibilité descendante avec Classic ASP,

Server.UrlEncode(str);

Est équivalent à:

HttpUtility.UrlEncode(str, Response.ContentEncoding);
CMS
la source
5

La même chose, Server.UrlEncode()appelleHttpUtility.UrlEncode()

Andleer
la source