web-dev-qa-db-fra.com

Comment faire UrlEncode sans utiliser System.Web?

J'essaie d'écrire une application client Windows qui appelle un site Web pour obtenir des données. Pour réduire au minimum l'installation, j'essaie uniquement d'utiliser dll dans le profil client .NET Framework . Le problème, c’est que j’ai besoin d’urlEncode pour certains paramètres. Existe-t-il un moyen simple de le faire sans importer System.Web.dll qui ne fait pas partie du fichier Pofile du client?

293
Martin Brown

System.Uri.EscapeUriString() peut être problématique avec certains caractères, il s’agissait pour moi d’un signe dièse/dièse '#' dans la chaîne.

Si cela vous pose problème, essayez:

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

Voici une réponse à la question SO qui explique la différence:

Quelle est la différence entre EscapeUriString et EscapeDataString?

et recommande d'utiliser Uri.EscapeDataString() dans tous les aspects.

296
ToddBFisher

Dans .Net 4.5+, utilisez WebUtility

Juste pour formater je soumets ceci comme une réponse.

Impossible de trouver de bons exemples en les comparant alors:

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

Les sorties:

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

Dans .Net 4.5+, utilisez WebUtility.UrlEncode

Cela semble répliquer HttpUtility.UrlEncode (pré-v4.0) pour les caractères les plus communs:
Uri.EscapeDataString(testString).Replace("%20", "+").Replace("'", "%27").Replace("~", "%7E")
Remarque: EscapeUriString conservera une chaîne uri valide, ce qui l’aidera à utiliser autant de caractères en texte brut que possible.

Voir cette réponse pour un tableau comparant les différents encodages:
https://stackoverflow.com/a/11236038/555798

Sauts de ligne Tous les éléments énumérés ici (autres que HttpUtility.HtmlEncode) convertiront "\n\r" en %0a%0d ou %0A%0D

N'hésitez pas à éditer ceci et à ajouter de nouveaux caractères à ma chaîne de test, ou laissez-les dans les commentaires et je les éditerai

242
Thymine

Vous pouvez utiliser

Uri.EscapeUriString (voir http://msdn.Microsoft.com/en-us/library/system.uri.escapeuristring.aspx )

52
Matthew Manela

Les réponses ici sont très bonnes, mais restent insuffisantes pour moi.

J'ai écrit une petite boucle qui compare Uri.EscapeUriString avec Uri.EscapeDataString pour tous les caractères de 0 à 255.

REMARQUE: Les deux fonctions ont l'intelligence intégrée selon laquelle les caractères supérieurs à 0x80 sont d'abord codés en UTF-8, puis en pourcentage.

Voici le résultat:

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

EscapeUriString doit être utilisé pour coder les URL, alors que EscapeDataString doit être utilisé pour coder par exemple le contenu d'un cookie, car les données de cookie ne doivent pas contenir les caractères réservés '=' et ';'.

19
Elmue

Il existe une version utilisable du profil client, classe System.Net.WebUtility, présente dans le profil client System.dll. Voici le lien MSDN:

WebUtility

15
Sprague

Voici un exemple d'envoi d'une demande POST qui code correctement les paramètres à l'aide du type de contenu application/x-www-form-urlencoded:

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

Pour UrlEncode sans utiliser System.Web:

String s = System.Net.WebUtility.UrlEncode(str);
//fix some different between WebUtility.UrlEncode and HttpUtility.UrlEncode
s = Regex.Replace(s, "(%[0-9A-F]{2})", c => c.Value.ToLowerInvariant());

plus de détails: https://www.samnoble.co.uk/2014/05/21/beware-webutility-urlencode-vs-httputility-urlencode/

0
Aaron Qiu