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

Contribuez .NET Discussion :

Extension de la classe WebClient pour exposer le Timeout


Sujet :

Contribuez .NET

  1. #1
    Invité
    Invité(e)
    Par défaut Extension de la classe WebClient pour exposer le Timeout


    La classe ExtendedWebClient dérivant de la classe WebClient vous permet de définir un timeout pour tout instance de la classe WebClient (Cette classe ne le permet pas bien qu'elle utilise la classe HttpWebRequest pour télécharger et téléverser des données).



    Code C# : 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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
     
    /// <summary>
    /// Classe dérivée de la classe WebClient
    /// </summary>
    public class ExtendedWebClient : WebClient
    {
        #region Fields
     
        private WebRequest request;
     
        #endregion // Fields
     
        #region Properties
     
        /// <summary>
        /// Obtient la durée du timeout
        /// </summary>
        public int Timeout { get; private set; }
     
        /// <summary>
        /// Obtient le container de cookies
        /// </summary>
        public CookieContainer CookieContainer { get; private set; }
     
        #endregion // Properties
     
        #region  Consctuctors
     
        /// <summary>
        /// Constructeur de la classe ExtendedWebClient
        /// </summary>
        /// <param name="timeout">Durée en millisecondes </param>
        public ExtendedWebClient(int timeout)
        {
            this.Timeout = timeout;
            this.CookieContainer = new CookieContainer();
        }
     
        #endregion // Constructors
     
        #region Overriden methods
     
        protected override WebRequest GetWebRequest(Uri address)
        {
            this.request = base.GetWebRequest(address);
     
            // S'il s'agit d'une instance de type HttpWebRequest alors on instancie le container de cookie
            if (this.request is HttpWebRequest)
            {
                (this.request as HttpWebRequest).CookieContainer = this.CookieContainer;
            }
     
            // Si this.Timeout <= 0 alors la valeur par défaut qui sera utilisée.
            this.request.Timeout = this.Timeout <= 0 ? this.request.Timeout : this.Timeout;
            return this.request;
        }
     
        #endregion // Overriden methods
    }
    Dernière modification par Invité ; 09/05/2012 à 13h54.

  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
    Oui, et pendant qu'on y est on peut aussi ajouter la gestion des cookies et autres réglages avancés

  3. #3
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Oui, et pendant qu'on y est on peut aussi ajouter la gestion des cookies et autres réglages avancés
    Yep! Pas faux. Sauf qu'en appliquant le principe YAGNI à mon projet actuel j'ai juste ajouté ce dont j'avais besoin .
    Sinon j'ajouterai volontiers ces réglages avancés et mettrai à jour le post une fois fait.

  4. #4
    Invité
    Invité(e)
    Par défaut
    J'ai mis à jour le post initial et voici les éléments suivants :
    • Ajout d'une propriété CookieContainer pour de la gestion des cookies (uniquement pour les requêtes HTTP/S)
    • Ajout d'une nouvelle méthode Abort pour abandonner une requête en cours d'exécution.
      Attention avec cette méthode, elle ne met pas à jour la propriété Cancelled qu'on récupère dans les gestionnaires d'évènement des différentes méthodes asynchrones qu'on sera amenées à utiliser. Il faudra se baser sur la propriété Status de l'erreur renvoyée en convertissant celle-ci en type WebException. Bref un petit exemple :
      Code C# : 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
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
       
      class Program
      {
          static void Main(string[] args)
          {
              ExtendedWebClient client = new ExtendedWebClient(5 * 60 * 1000);
              client.DownloadDataCompleted += clientDownloadDataCompleted;
              client.DownloadDataAsync(new Uri("http://www.developpez.com"));
              client.Abort();
              Console.ReadKey();
          }
       
          private static void clientDownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
          {
       
              WebException we = e.Error as WebException;
              if (we != null)
              {
                  // On regarde la propriété Status de l'objet WebException parce que e.Cancelled vaut toujours false 
                  // lorsqu'on abandonne notre précédente requête.
                  if (we.Status == WebExceptionStatus.RequestCanceled)
                  {
                      Console.WriteLine("Abandon : {0}", we.Message);
                  }
                  else
                  {
                      Console.WriteLine("Autre chose : {0}", we.Message);
                  }
              }
              else if (e.Error != null)
              {
                  Console.WriteLine("Autre chose : {0}", e.Error.Message);
              }
              else
              {
                  Console.WriteLine("Appramment tout s'est bien passé");
              }
          }
      }


    Si vous avez d'autres choses à ajouter à cette classe alors n'hésitez pas.

  5. #5
    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 h2s84 Voir le message
    [*] Ajout d'une nouvelle méthode Abort pour abandonner une requête en cours d'exécution.
    Euh, c'est cool, mais ça existe déjà : CancelAsync
    Et ça met bien à jour la propriété Cancelled

    Pour le CookieContainer, à mon avis tu le gères pas comme il faudrait :
    - il faut qu'il soit initialisé avant le GetWebRequest, sinon l'utilisateur peut pas ajouter des Cookies à envoyer avec la requête
    - il ne faut pas le réinitialiser à chaque fois, mais le réutiliser pour les requêtes suivantes. Comme ça les cookies sont automatiquement retransmis au serveur (cookies d'authentification par exemple)

  6. #6
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Euh, c'est cool, mais ça existe déjà : CancelAsync
    Et ça met bien à jour la propriété Cancelled
    hum... Coment j'ai pu manqué ça. Ok c'est retiré

    Citation Envoyé par tomlev Voir le message
    Pour le CookieContainer, à mon avis tu le gères pas comme il faudrait :
    - il faut qu'il soit initialisé avant le GetWebRequest, sinon l'utilisateur peut pas ajouter des Cookies à envoyer avec la requête
    Je n'ai pas trop compris mais un autre problème est que je me demande où est-ce que je vais pouvoir la mettre l'inistialisation surtout que j'ai besoin de savoir s'il s'agit d'une HttpWebRequest ? Je cherche...

    Citation Envoyé par tomlev Voir le message
    - il ne faut pas le réinitialiser à chaque fois, mais le réutiliser pour les requêtes suivantes. Comme ça les cookies sont automatiquement retransmis au serveur (cookies d'authentification par exemple)
    Parfaitement raison avec l'exemple de l’authentification. Ok je l'initialise dans le constructeur même si on sait que les cookies sont utiles uniquemeent pour HttpWebRequest.

  7. #7
    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 h2s84 Voir le message
    Je n'ai pas trop compris
    Si je fais ça avec ton code d'origine, ça plante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var wc = new ExtendedWebClient();
    wc.CookieContainer.Add(...); // NullReferenceException
    Et même si CookieContainer est initialisé dans le constructeur, si tu le réinitialises dans le GetWebRequest les cookies ajoutés avant sont perdus

    Citation Envoyé par h2s84 Voir le message
    mais un autre problème est que je me demande où est-ce que je vais pouvoir la mettre l'inistialisation surtout que j'ai besoin de savoir s'il s'agit d'une HttpWebRequest ? Je cherche...
    Bah tu t'en fous... si c'est pas une HttpWebRequest, tu ignores la propriété CookieContainer.

  8. #8
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Si je fais ça avec ton code d'origine, ça plante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var wc = new ExtendedWebClient();
    wc.CookieContainer.Add(...); // NullReferenceException
    Je confirme.

    Citation Envoyé par tomlev Voir le message
    Et même si CookieContainer est initialisé dans le constructeur, si tu le réinitialises dans le GetWebRequest les cookies ajoutés avant sont perdus
    C'est normal... je pense. bah ! Si tu crées une nouvelle instance d'une classe WebClient c'est normal que le CookieContainer soit réinitialiser non ? Je sais tu ne penses pas à mettre cette propriété en statique mais peut-être que tu veux que le container soit passé en paramètre au constructeur ?

    Citation Envoyé par tomlev Voir le message
    Bah tu t'en fous... si c'est pas une HttpWebRequest, tu ignores la propriété CookieContainer.
    Bon finalement je pense que utiliser les Header est plus simple après tout en lisant ceci.

  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
    Citation Envoyé par h2s84 Voir le message
    C'est normal... je pense. bah ! Si tu crées une nouvelle instance d'une classe WebClient c'est normal que le CookieContainer soit réinitialiser non ?
    Si tu crées une nouvelle instance, oui, mais quand tu réinitialisais le CookieContainer dans le GetWebRequest, ça faisait que ce code là ne marchait pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    var wc = new ExtendedWebClient();
    wc.CookieContainer.Add(...);
    wc.DownloadString(...); // le cookie ajouté au dessus est perdu...
    Avec le code actuel c'est OK

    Citation Envoyé par h2s84 Voir le message
    Je sais tu ne penses pas à mettre cette propriété en statique mais peut-être que tu veux que le container soit passé en paramètre au constructeur ?
    Non, surtout pas en statique ! ça ferait que toutes les instances de la classe partageraient le même CookieContainer, ce qui est extrêmement gênant...
    Le passer en paramètre, c'est possible, mais pas indispensable. Tu peux toujours faire 2 constructeurs...

Discussions similaires

  1. Réponses: 21
    Dernier message: 01/03/2006, 17h51
  2. [débutante]utiliser les classes css pour surligner des liens
    Par Mitaka dans le forum Général JavaScript
    Réponses: 18
    Dernier message: 06/01/2006, 10h37
  3. recherche une classe KZtransImg pour delphi 7
    Par plante20100 dans le forum Composants VCL
    Réponses: 2
    Dernier message: 21/07/2005, 14h56
  4. Extension d'un reseau existant pour le WIFI
    Par phipamadia dans le forum Développement
    Réponses: 4
    Dernier message: 22/06/2004, 18h07

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