2010-12-11 60 views
0

Je dois consommer un service qui prend un paramètre GET nommé "names []".Empêche le C# des parenthèses d'encodage dans la chaîne de requête

Par exemple: GET http://example.com/name2id?names []=john

Lorsque je tente de consommer que C# en utilisant un WebClient, les supports est encodée à% 5B% 5D, dont les Servies ne comprend pas. Lorsque j'envoie ce qui précède en utilisant mon navigateur (non-codé), tout fonctionne bien.

Heres l'exemple qui ne fonctionne pas:

using (var client = new System.Net.WebClient()) 
{ 
    response = client.DownloadString(new Uri("http://example.com/name2id?names[]=john")); 
} 

Contrôlée par Fiddler, Heres la demande:

GET http://example.com/name2id?names%5B%5D=john HTTP/1.1 
Host: example.com 
Connection: Keep-Alive 

est-il un moyen de rendre le cadre codait pas l'URL, ou un autre moyen de contourner ce problème?

P.S. Je ne contrôle pas l'API, donc je ne peux pas changer ça.

MISE À JOUR:

C'est un peu bizarre. J'ai trouvé une solution, changer mon code C# à:

using (var client = new System.Net.WebClient()) 
{ 
    response = client.DownloadString(new Uri("http://example.com/name2id?names[]=john", true)); 
} 

Notez le dontEscape booléenne à Uri. C'est en fait obsolète, mais ça marche? Quelqu'un peut-il expliquer cela? Comme je comprends RFC2396 [] ne sont pas des caractères valides dans un URI

+0

Je pense que la seule façon de contourner est de ne pas utiliser un client Web mais de faire une demande manuelle en utilisant un socket normal, mais même alors, ce ne serait pas vraiment une demande valide, donc je se demander si le service l'accepterait – Doggett

+0

Vous pouvez toujours demander à fournir d'utiliser des noms raisonnables dans leurs arguments, et bien sûr vérifier qu'ils exigent vraiment "[]" dans le nom. Cette exigence me semble plutôt ridicule. –

+0

Voir la mise à jour. –

Répondre

0

Comme mentionné par CodeInChaos, l'URL n'est pas valide selon RFC2396.

Pour faire C# pas échapper à des caractères non valides, la méthode surchargée d'URI peut être CAFR:

new Uri("http://example.com/name2id?names[]=john", true) 

Cependant, cette méthode est dépréciée mais apparemment il fonctionne encore. Je dois vivre avec l'avertissement surgissant :)

1

Donc, il me semble que votre service attend une requête http malformée.

query   = *uric 
uric   = reserved | unreserved | escaped 
unreserved = alphanum | mark 
mark   = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" 
reserved  = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | "," 
escaped  = "%" hex hex 

http://www.ietf.org/rfc/rfc2396.txt

+0

C'est vrai, mais c'est ce que le service attend, et je ne peux pas changer cela. Cela fonctionne avec un navigateur et j'ai trouvé une solution. Je vais mettre à jour la question. –

+0

La RFC 3986 (http://tools.ietf.org/html/rfc3986#section-2.2) répertorie les crochets en tant que caractères réservés. Cependant, "réservé" signifie qu'ils sont seulement * éligibles * pour un traitement spécial, en fonction des besoins du serveur. C'est un problème majeur avec toutes les options HTTP actuelles dans .NET dans 4.5, car elles échappent toutes à l'URI à un moment donné. – McGuireV10

0

Etes-vous sûr que les caractères codés est le vrai problème?

Les caractères sont codés correctement par la classe WebClient. Si le service ne peut pas gérer les caractères correctement codés, le service est interrompu.

Si le service est cassé de cette façon, et vous devez l'utiliser quand même, alors vous devez trouver une manière différente d'envoyer la demande.

0

Vous devriez juste être en mesure passer l'URI comme une chaîne

Ainsi faisant

response = client.DownloadString("http://example.com/name2id?names[]=john"); 

Si le travail sans coder l'URL. Je n'ai pas essayé mais je me suis peut-être trompé.