EXEMPLE UTILISATION HTTPWEBREQUEST, AFFICHER RÉPONSE HTTP À UNE REQUÊTE GET POST
cs_MnX
Messages postés3Date d'inscriptionsamedi 18 novembre 2000StatutMembreDernière intervention 8 juin 2005
-
8 juin 2005 à 12:23
DevNovice -
25 janv. 2016 à 14:16
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.
bonjour, j'aurai besoin de vous
je souhaite savoir qu'est-ce qu'il faut mettre dans le champs serveur?
Thanks
cs_CrazyBlade
Messages postés2Date d'inscriptionmardi 17 mars 2009StatutMembreDernière intervention28 février 2012 28 févr. 2012 à 05:44
Merci !
cs_gipp
Messages postés12Date d'inscriptionlundi 19 mars 2001StatutMembreDernière intervention27 mai 2008 31 août 2007 à 03:50
Un très grand merci pour ce code !
Tu m'as sauvé après 2 mois de galère !!!
Gilles
TeBeCo
Messages postés467Date d'inscriptionlundi 24 juin 2002StatutMembreDernière intervention 9 mars 2011 19 août 2007 à 16:30
Suite à l'utilisation de ce code j'ai apporté quelques modification qui pourront peut être résoudre quelques problème qui sont apparue chez moi :
Contexte : récupération de fichiers images au travers d'un formulaire de méthode "POST"
Premier problème : Le "rea.ReadToEnd()" lit les caractère issue de la réponse du serveur au travers d'un encoding type "Europe de l'ouest" :
StreamReader rea = new StreamReader(resin, Encoding.GetEncoding(850));
cela peux deja poser problème si l'encoding utilisé ne correspond pas a celui requis pour ce type de donnée car les image sont en format binaire peut importe l'encoding pour en faire des caractères.
Donc il faudrait dans ce cas présent tout simplement éviter de passer par un StreamReader qui quoi qu'il arrive fera TOUJOURS un décodage meme si vous n'en spécifier pas il prendra celui par default.
Je me suis donc attaquer directement au flux lui même :
Stream resin = res.GetResponseStream();
le problème qui se pose avec ce genre de flux est de detecté la taille des donnée à lire car il n'y a pas (ou alors pas vu) d'indicateur de fin de flux.
pour cela :
int TailleFichier = int.Parse(res.Headers.Get("Content-length"));
afin de récupérer la taille du fichier renvoyé par le serveur
A partir de la il faut reussir à lire les données suffisament vite car par exemple le serveur ou j'étais limite la durée de vie du stream à 30 secondes maximum une fois le delais impartit le flux est refermé.
J'ai utilisé (au début) une solution pas forcément optimale mais qui semble relativement bien marcher :
const int TaillePacket = 1024;
struct Packet {
public byte[] Data;
public int nbOctet;
}
System.Collection.Generic.Queue Fichier;
/* ... */
Stream resin = res.GetResponseStream();
int TailleFichier = int.Parse(res.Headers.Get("Content-length"));
int nbOctetRecu = 0;
Fichier = new System.Collection.Generic.Queue((TailleFichier + TaillePacket -1)/TaillePacket );
while(nbOctetRecu <= TailleFichier)
{
Packet PacketEnCour = new Packet();
PacketEnCour.Data = new byte[TaillePacket];
PacketEnCour.nbOctet = resin.Read(PacketEnCour.Data, 0, TaillePacket);
Fichier.Enqueue(PacketEnCour);
nbOctetRecu += PacketEnCour.nbOctet;
}
une fois fait il reste plus qu'à dépilé tout ca bétement
Packet tmp;
while(Fichier.Count > 0)
{
tmp = Fichier.Dequeue();
//traitement en prenant compte de la longueur des octets present dedans
}
pourquoi ne pas mettre le buffer de 1024 directement à la place d'une structure ?
pour une connexion relativement lente le serveur à pas le temps d'envoyer 1024 octet le temps d'une boucle de lecture resultat il y a moins que 1024 octet à prendre en compte au début on se demande pourquoi il envoi 51 paquets de 1K pour des image de 36K :p
sinon la version plus simple pour une image et nettement plus rapide :
Stream resin = res.GetResponseStream();
if(res.Headers.Get("Content-type").ToLower() == "image/jpeg".ToLower())
{
Image img = Image.FromStream(resin);
img.Save("C:\\monimage.jpg");
}
voila me suis dit que ca pourrais serveir à qq personne
BaFM
Messages postés64Date d'inscriptionmercredi 24 juillet 2002StatutMembreDernière intervention26 novembre 2009 17 août 2007 à 17:55
Alors pour répondre simplement : ben ca fonctionne comme pour les navigateurs web...
Le paramètre passé à la dll, donc serveur IIS, c'est le nom de l'action à appeler.
Ensuite, il faut que tu fasse gaffe que tes données poste soit bien encodé comme si tu passais les informations par url. avec les '+' et les '%xx'.
Après qu'il ne résolve pas, c'est que tu doit avoir fait une erreur de saisie. Puisque je reconstruit l'url à partir des paramètres.
TeBeCo
Messages postés467Date d'inscriptionlundi 24 juin 2002StatutMembreDernière intervention 9 mars 2011 17 août 2007 à 12:54
Je rencontre actuellement un problème sur un form de type post sur une url du genre :
POST="http:///madll.dll?GetTitle"
sachant que le serveur auquel corespond l'ip n'est pas a moi et apparement ne repond pas au ping
j'essaye de lui passé environ 10-12 champs hidden en content et il m'indique une erreur comme quoi il arrrive pas a resoudre l'hote distant il me semble
plusieur pb se sont poser a moi pour le choix de remplissage des champs
que faire du "?GetTitle"
est ce que ca marche aussi avec les dll car ici c'est bel et bien une dll (et ca marche bien depuis mon navigateur)
comment etre sur que j'ai bien passer les champs de type hidden (meme si qqsoit leur valeur pour le moment l'erreur reste la même)
je rentrerai bcp trop tard ce soir pour te croiser sur le chan de CS d'ailleurs donc hesite pas a envoyer un mail et/ou repondre ici d'ici la :D
cs_Bidou
Messages postés5487Date d'inscriptiondimanche 4 août 2002StatutMembreDernière intervention20 juin 201361 9 sept. 2006 à 20:09
Je vais devoir faire une classe qui va gérer ça je pense, mais actuellement j'ai des assez gros problèmes avec mes cookies : si j'utilise le CookieContainer courant, ça ne fontionne pas, je suis obligé de faire une manip' de ce genre la :
foreach (Cookie c in cookieContainer.GetCookies(new Uri("http://xxxxxxx")))
{
myContainer.Add(new Cookie(c.Name, c.Value, "/", "xx"));
}
pourtant mon CookieContainer semble contenir les informations correctes.
Bizarre bizarre...
BaFM
Messages postés64Date d'inscriptionmercredi 24 juillet 2002StatutMembreDernière intervention26 novembre 2009 9 sept. 2006 à 17:39
Selon la spécification, l'url retournée par le location doit être absolue. Si ce n'est pas le cas, alors c'est que le site ne suis pas les spécifications. Enfin, une adaptation est fesable mais si ca fonctionne pas, il suffit de corriger l'url soit même, non ? :)
Je ne saurais le dire pour les cookies, parce que en faite, je fait juste un transfert des cookies des réponses précédentes vers la nouvelle requête, pour ceux qui s'y appliquent, enfin, le système fait le tri.
Sinon, merci pour ton commentaire.
PS : Je ne ferait une nouvelle version que si elle m'est nécessaire. Cependant, si quelqu'un me soumet des améliorations, je pourrais très bien les intégrer.
cs_Bidou
Messages postés5487Date d'inscriptiondimanche 4 août 2002StatutMembreDernière intervention20 juin 201361 9 sept. 2006 à 12:45
Bonne source mais :
- newURL n'a pas une valeur correcte. En effet, le header location retourne un path qui n'est pas absolu, ce qui nous donne un beau URI exception dans le
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(URL);
(si au moins une boucle avec redirection est faite)
- Chez moi, ton sysème de cookie ne fonctionne pas, je n'ai pas encore trouvé pour quelle raison...
Sinon l'idée de la source est bonne, mais faudrait encore la travailler...
8/10
BaFM
Messages postés64Date d'inscriptionmercredi 24 juillet 2002StatutMembreDernière intervention26 novembre 2009 8 juin 2005 à 18:51
Ba en même temps j'ai trouvé toutes mes informations dans la MSDN ;). Bon ca a mit le temps et j'avais la RFC2616 (HTTP 1.1) sous la main. Sinon j'utilise le .NET Framework 1.1.4322 si ca peut t'aider.
cs_MnX
Messages postés3Date d'inscriptionsamedi 18 novembre 2000StatutMembreDernière intervention 8 juin 2005 8 juin 2005 à 15:33
J'ai presque oublié, je ne sais pas si c'est lié à ma version du framework .Net mais HttpWebRequest ne possède pas de méthode Close() chez moi. Encore merci, ton exemple m'a permis de comprendre le fonctionnement bien plus vite que je ne l'aurais fais en n'utilisant que les infos données sur msdn.
BaFM
Messages postés64Date d'inscriptionmercredi 24 juillet 2002StatutMembreDernière intervention26 novembre 2009 8 juin 2005 à 13:25
Merci,
Mais en fait, t'a le zip qui contient tout ce qui est nécessaire. Comme je l'ai écris, j'ai mit la fonction surtout pour mettre les commentaires sur le code. Pour le premier aperçu des fonctionalités.
Mais sinon tu peut exécuter l'application pour voir ce que ca donne finalement.
MyGoddess
cs_MnX
Messages postés3Date d'inscriptionsamedi 18 novembre 2000StatutMembreDernière intervention 8 juin 2005 8 juin 2005 à 12:23
Exemple très instructif. Juste un petit problème tu utilise des objets qui sont surement définis dans la classe propriétaire de la méthode. Résultat, il faut un peu de travail pour se rendre compte que les objets comme les cookies et autres ne sont pas valides et soit les remplacer, soit ne pas les utiliser. L'alternative offerte par ce morceau de code à la redirection automatique est très interessante car elle offre un contrôle sur ce que fais le programme. J'avais surtout besoin d'un contrôle des erreurs avec alerte donc des exception avec exemple d'utilisation.
25 janv. 2016 à 14:16
je souhaite savoir qu'est-ce qu'il faut mettre dans le champs serveur?
Thanks
28 févr. 2012 à 05:44
31 août 2007 à 03:50
Tu m'as sauvé après 2 mois de galère !!!
Gilles
19 août 2007 à 16:30
Contexte : récupération de fichiers images au travers d'un formulaire de méthode "POST"
Premier problème : Le "rea.ReadToEnd()" lit les caractère issue de la réponse du serveur au travers d'un encoding type "Europe de l'ouest" :
StreamReader rea = new StreamReader(resin, Encoding.GetEncoding(850));
cela peux deja poser problème si l'encoding utilisé ne correspond pas a celui requis pour ce type de donnée car les image sont en format binaire peut importe l'encoding pour en faire des caractères.
Donc il faudrait dans ce cas présent tout simplement éviter de passer par un StreamReader qui quoi qu'il arrive fera TOUJOURS un décodage meme si vous n'en spécifier pas il prendra celui par default.
Je me suis donc attaquer directement au flux lui même :
Stream resin = res.GetResponseStream();
le problème qui se pose avec ce genre de flux est de detecté la taille des donnée à lire car il n'y a pas (ou alors pas vu) d'indicateur de fin de flux.
pour cela :
int TailleFichier = int.Parse(res.Headers.Get("Content-length"));
afin de récupérer la taille du fichier renvoyé par le serveur
A partir de la il faut reussir à lire les données suffisament vite car par exemple le serveur ou j'étais limite la durée de vie du stream à 30 secondes maximum une fois le delais impartit le flux est refermé.
J'ai utilisé (au début) une solution pas forcément optimale mais qui semble relativement bien marcher :
const int TaillePacket = 1024;
struct Packet {
public byte[] Data;
public int nbOctet;
}
System.Collection.Generic.Queue Fichier;
/* ... */
Stream resin = res.GetResponseStream();
int TailleFichier = int.Parse(res.Headers.Get("Content-length"));
int nbOctetRecu = 0;
Fichier = new System.Collection.Generic.Queue((TailleFichier + TaillePacket -1)/TaillePacket );
while(nbOctetRecu <= TailleFichier)
{
Packet PacketEnCour = new Packet();
PacketEnCour.Data = new byte[TaillePacket];
PacketEnCour.nbOctet = resin.Read(PacketEnCour.Data, 0, TaillePacket);
Fichier.Enqueue(PacketEnCour);
nbOctetRecu += PacketEnCour.nbOctet;
}
une fois fait il reste plus qu'à dépilé tout ca bétement
Packet tmp;
while(Fichier.Count > 0)
{
tmp = Fichier.Dequeue();
//traitement en prenant compte de la longueur des octets present dedans
}
pourquoi ne pas mettre le buffer de 1024 directement à la place d'une structure ?
pour une connexion relativement lente le serveur à pas le temps d'envoyer 1024 octet le temps d'une boucle de lecture resultat il y a moins que 1024 octet à prendre en compte au début on se demande pourquoi il envoi 51 paquets de 1K pour des image de 36K :p
sinon la version plus simple pour une image et nettement plus rapide :
Stream resin = res.GetResponseStream();
if(res.Headers.Get("Content-type").ToLower() == "image/jpeg".ToLower())
{
Image img = Image.FromStream(resin);
img.Save("C:\\monimage.jpg");
}
voila me suis dit que ca pourrais serveir à qq personne
17 août 2007 à 17:55
Le paramètre passé à la dll, donc serveur IIS, c'est le nom de l'action à appeler.
Ensuite, il faut que tu fasse gaffe que tes données poste soit bien encodé comme si tu passais les informations par url. avec les '+' et les '%xx'.
Après qu'il ne résolve pas, c'est que tu doit avoir fait une erreur de saisie. Puisque je reconstruit l'url à partir des paramètres.
17 août 2007 à 12:54
POST="http:///madll.dll?GetTitle"
sachant que le serveur auquel corespond l'ip n'est pas a moi et apparement ne repond pas au ping
j'essaye de lui passé environ 10-12 champs hidden en content et il m'indique une erreur comme quoi il arrrive pas a resoudre l'hote distant il me semble
plusieur pb se sont poser a moi pour le choix de remplissage des champs
que faire du "?GetTitle"
est ce que ca marche aussi avec les dll car ici c'est bel et bien une dll (et ca marche bien depuis mon navigateur)
comment etre sur que j'ai bien passer les champs de type hidden (meme si qqsoit leur valeur pour le moment l'erreur reste la même)
je rentrerai bcp trop tard ce soir pour te croiser sur le chan de CS d'ailleurs donc hesite pas a envoyer un mail et/ou repondre ici d'ici la :D
9 sept. 2006 à 20:09
foreach (Cookie c in cookieContainer.GetCookies(new Uri("http://xxxxxxx")))
{
myContainer.Add(new Cookie(c.Name, c.Value, "/", "xx"));
}
pourtant mon CookieContainer semble contenir les informations correctes.
Bizarre bizarre...
9 sept. 2006 à 17:39
Je ne saurais le dire pour les cookies, parce que en faite, je fait juste un transfert des cookies des réponses précédentes vers la nouvelle requête, pour ceux qui s'y appliquent, enfin, le système fait le tri.
Sinon, merci pour ton commentaire.
PS : Je ne ferait une nouvelle version que si elle m'est nécessaire. Cependant, si quelqu'un me soumet des améliorations, je pourrais très bien les intégrer.
9 sept. 2006 à 12:45
- newURL n'a pas une valeur correcte. En effet, le header location retourne un path qui n'est pas absolu, ce qui nous donne un beau URI exception dans le
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(URL);
(si au moins une boucle avec redirection est faite)
- Chez moi, ton sysème de cookie ne fonctionne pas, je n'ai pas encore trouvé pour quelle raison...
Sinon l'idée de la source est bonne, mais faudrait encore la travailler...
8/10
8 juin 2005 à 18:51
8 juin 2005 à 15:33
8 juin 2005 à 13:25
Mais en fait, t'a le zip qui contient tout ce qui est nécessaire. Comme je l'ai écris, j'ai mit la fonction surtout pour mettre les commentaires sur le code. Pour le premier aperçu des fonctionalités.
Mais sinon tu peut exécuter l'application pour voir ce que ca donne finalement.
MyGoddess
8 juin 2005 à 12:23