IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Forms Discussion :

[C#] Récupérer un pdf généré à la volée


Sujet :

Windows Forms

  1. #1
    Membre confirmé Avatar de Gunny
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2007
    Messages
    188
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Danemark

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2007
    Messages : 188
    Points : 624
    Points
    624
    Par défaut [C#] Récupérer un pdf généré à la volée
    Bonjour,

    Je me casse la tête depuis quelques heures là dessus et je ne trouve pas de solution.
    J'utilise un contrôle webbrowser pour crawler un site web qui requiert une double authentification : une boîte de dialogue système (htaccess probablement) et ensuite un formulaire web.
    A un moment je dois enregistrer un pdf qui est généré par le site. Je n'ai donc pas d'url directe vers le document, juste une url "classique" vers une jsp.
    J'ai exploré la piste évidente du webclient. Le problème étant que le WebClient n'étant pas authentifié via le formulaire web, au lieu de me récupérer le pdf, il me récupère la page qui est affichée lorsque l'on essaye d'appeler l'url sans s'être authentifié via le formulaire. Les credentials passent l'authentification https mais c'est tout.
    Ensuite j'ai essayé d'utiliser les propriétés Document et DocumentStream de mon contrôle WebBrowser dans le gestionnaire d'évènement DocumentCompleted, mais sans succès. En effet si j'appelle la fonction Navigate() sur l'url du pdf, c'est Adobe Reader qui se lance, et par conséquent le document pdf n'est pas chargé dans la propriété Document (dans celle-ci se trouve en fait la page précédente).
    J'essaye d'explorer la piste de simuler un clic droit>enregistrer sous mais sans grand succès.

    Quelqu'un a-t-il une idée ?

    Merci beaucoup !

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par Gunny Voir le message
    Le problème étant que le WebClient n'étant pas authentifié via le formulaire web, au lieu de me récupérer le pdf, il me récupère la page qui est affichée lorsque l'on essaye d'appeler l'url sans s'être authentifié via le formulaire. Les credentials passent l'authentification https mais c'est tout.
    Le problème est que de base, WebClient ne sait pas gérer les cookies. Donc l'authentification par formulaire que tu fais est aussitôt "oubliée", vu que tu ne retransmets pas les cookies que tu as reçus en t'authentifiant.

    Heureusement c'est assez facile d'ajouter cette fonctionnalité :

    - Crée une classe qui hérite de WebClient (appelle la par exemple WebClientEx)
    - Ajoute une propriété CookieContainer (de type CookieContainer)
    - Override la méthode GetWebRequest pour gérer les cookies de la HttpWebRequest


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public class WebClientEx : WebClient
    {
        public CookieContainer CookieContainer { get; set; }
     
        protected override WebRequest GetWebRequest(Uri address)
        {
            var req = base.GetWebRequest(address);
            var httpReq = req as HttpWebRequest;
            if (httpReq != null)
            {
                httpReq.CookieContainer = this.CookieContainer;
            }
            return req;
        }
    }

    Pour l'utiliser, initialise la propriété CookieContainer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    var client = new WebClientEx();
    client.CookieContainer = new CookieContainer();
    ...
    Si tu réutilises le même WebClientEx pour plusieurs requêtes successives (ou que tu réutilises le même CookieContainer avec plusieurs WebClientEx), les cookies seront conservés entre chaque requête, et ça devrait fonctionner comme tu veux

  3. #3
    Membre confirmé Avatar de Gunny
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2007
    Messages
    188
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Danemark

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2007
    Messages : 188
    Points : 624
    Points
    624
    Par défaut
    Merci !

    J'ai donc écrit ce code (je vous passe les appels à mon fichier config) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    WebClientEx client = new WebClientEx();
    client.Proxy.Credentials = CredentialCache.DefaultNetworkCredentials;
    client.Credentials = new NetworkCredential(login, pass);
    client.CookieContainer = new CookieContainer();
     
    //Authentification formulaire
    string url = "urlForm";
    NameValueCollection formData = new NameValueCollection();
    formData["txtLogin"] = login2;
    formData["txtMdp"] = pass2;
     
    byte[] responseBytes = client.UploadValues(url, "POST", formData);
     
     
    // On enregistre temporairement le PDF
    string tempPath = Path.GetTempFileName() + ".pdf";
    client.DownloadFile("URLpdf", tempPath);
    Et... ça ne fonctionne pas, mon code reste bloqué lors de l'appel à UploadValues (erreur 401). D'où cela peut-il venir ?

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par Gunny Voir le message
    Et... ça ne fonctionne pas, mon code reste bloqué lors de l'appel à UploadValues. D'où cela peut-il venir ?
    Bizarre... et si tu vires le CookieContainer ça bloque pas ?

  5. #5
    Membre confirmé Avatar de Gunny
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2007
    Messages
    188
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Danemark

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2007
    Messages : 188
    Points : 624
    Points
    624
    Par défaut
    Ca ne change rien non, toujours erreur 401. Pourtant mes credentials sont corrects.

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Bizarre... sans le CookieContainer ça doit pourtant revenir au même qu'avec un WebClient normal

  7. #7
    Membre confirmé Avatar de Gunny
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2007
    Messages
    188
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Danemark

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2007
    Messages : 188
    Points : 624
    Points
    624
    Par défaut
    Oui c'est bizarre que ça me fait un 401, comme si mes credentials étaient erronés.

    En effet, si je me contente de faire client.downloadFile sans définir les credentials, je tombe sur une erreur 401 (normal). Mais, si je les mets, le webclient me télécharge la page d'erreur affichée s'il l'on est authentifié auprès du serveur mais sans s'être identifié via le formulaire web. Ca veut donc bien dire que ça ne vient pas de là, a priori...

  8. #8
    Membre confirmé Avatar de Gunny
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2007
    Messages
    188
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Danemark

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2007
    Messages : 188
    Points : 624
    Points
    624
    Par défaut
    Testé ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    CredentialCache cc = new CredentialCache();
    cc.Add(new Uri("http://www.lesite.fr/"), "Digest", new NetworkCredential("login", "pass", "www.lesite.fr"));
    client.Credentials = cc;
    Mais sans plus de succès... J'ai toujours une erreur 401 à l'appel de UploadValues.

    edit : mes credentials initiaux ont pourtant bien l'air de fonctionner. Si j'essaye d'appeler la fonction downloadFile de mon webclient sur un fichier quelconque accessible après l'authentification htaccess, mais sans avoir besoin de se connecter via le formulaire web (exemple : une image), il est bien téléchargé. Alors pourquoi l'erreur 401 quand j'appelle la fonction UploadValues ?

  9. #9
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Je sais pas trop...

    Tu es sûr que c'est "Digest" et pas "Basic" l'authentification à utiliser ?

  10. #10
    Membre confirmé Avatar de Gunny
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2007
    Messages
    188
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Danemark

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2007
    Messages : 188
    Points : 624
    Points
    624
    Par défaut
    J'ai essayé avec les deux, ça ne change rien. VIsiblement ça ne vient pas de mes credentials de toute façon.

    J'ai essayé d'analyser les trames HTTP avec Fiddler et même en recopiant les headers et en vérifiant que la requête envoyée par le webclient est quasi-identique à celle envoyée par mon navigateur ça m'envoie quand même un 401.

    Hmmm...

  11. #11
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par Gunny Voir le message
    quasi-identique
    C'est quoi les différences ?

  12. #12
    Membre confirmé Avatar de Gunny
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2007
    Messages
    188
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Danemark

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2007
    Messages : 188
    Points : 624
    Points
    624
    Par défaut
    Voici la requête postée par mon navigateur (IE en l'occurence) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    POST http://www.lesite.fr/actionform.jsp HTTP/1.1
    Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */*
    Referer: http://www.lesite.fr/index.jsp
    Accept-Language: fr
    Content-Type: application/x-www-form-urlencoded
    UA-CPU: x86
    Accept-Encoding: gzip, deflate
    User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
    Proxy-Connection: Keep-Alive
    Content-Length: 46
    Host: www.lesite.fr
    Pragma: no-cache
    Cookie: JSESSIONID=6EC0B9CAF20E6914B9E3F8FAEBA16504.60B0ABCC71ADFA8D67
    Authorization: Basic xxxxx==
     
    login=xxx&password=xxx&mode=Valider+%3E%3E
    Et par mon WebCLient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    POST http://www.lesite.fr/actionform.jsp HTTP/1.1
    Accept-Language: fr
    UA-CPU: x86
    Accept-Encoding: gzip, deflate
    Pragma: no-cache
    Authorization: Basic xxxxx==
    Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */*
    Content-Type: application/x-www-form-urlencoded
    Referer: http://www.lesite.fr/index.jsp
    User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
    Host: www.lesite.fr
    Content-Length: 46
    Expect: 100-continue
    Proxy-Connection: Keep-Alive
     
    login=xxx&password=xxx&mode=Valider+%3e%3e

  13. #13
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    OK, donc les 2 seules différences sont :
    - IE envoie un cookie JSESSIONID: je pense pas que ce soit lié à ça, mais on sait jamais... essaie peut-être de faire une première requête sur le site avant le login, pour récupérer un cookie de session
    - IE envoie pas l'en-tête Expect: 100-continue : j'ai déjà vu des trucs bizarres à cause de cet en-tête, il faudrait peut-être essayer de le virer. Dans la méthode GetWebRequest, essaie d'ajouter ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    request.ServicePoint.Expect100Continue = false;

  14. #14
    Membre confirmé Avatar de Gunny
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2007
    Messages
    188
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Danemark

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2007
    Messages : 188
    Points : 624
    Points
    624
    Par défaut



    Voici la requete après avoir fait ces deux choses :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    POST http://www.lesite.fr/actionForm.jsp HTTP/1.1
    Accept-Language: fr
    UA-CPU: x86
    Accept-Encoding: gzip, deflate
    Pragma: no-cache
    Authorization: Basic xxxx==
    Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */*
    Content-Type: application/x-www-form-urlencoded
    Referer: http://www.lesite.fr/index.jsp
    User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
    Host: www.lesite.fr
    Cookie: JSESSIONID=FFC468F3FCDDF35581C93911D683929A.21B492F430A9C3B526
    Content-Length: 46
    Proxy-Connection: Keep-Alive
     
    login=xxx&password=xxx&mode=Valider+%3e%3e
    Et bien... Erreur 401 toujours.

  15. #15
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par Gunny Voir le message
    Comme tu dis

    Là je sais vraiment plus quoi te proposer...

  16. #16
    Membre confirmé Avatar de Gunny
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2007
    Messages
    188
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Danemark

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2007
    Messages : 188
    Points : 624
    Points
    624
    Par défaut
    Bon ben je vais devoir passer au plan B qui n'a rien à voir

    Tant pis, merci pour l'aide !

Discussions similaires

  1. Réponses: 8
    Dernier message: 22/07/2012, 18h26
  2. Réponses: 3
    Dernier message: 19/05/2006, 17h08
  3. [MySQL] Récupérer Code HTML généré par PHP
    Par @ngelofdeath dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 26/04/2006, 21h51
  4. [Système] récupérer l'HTML généré par ma page PHP
    Par saint-pere dans le forum Langage
    Réponses: 2
    Dernier message: 27/09/2005, 10h19

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo