Hayadi's Blog

jeudi, février 02, 2006

Envoi et réception de mails avec le framework 2.0

La gestion de l'envoi et de la réception de mails sont des besoins récurrents dans bon nombre d'applications. Le but de cet article est donc de vous présenter les nombreuses possibilités offertes par .Net

I -Envoi de mail

Dans cette première partie, nous allons voir ce que j'estime être le plus intéressant avec les mails: l'envoi. L'envoi de mail peut être utilisé de diverses manières: notification, envoi de rapport ou mail "personnel". L'équipe Microsoft a bien tenu compte de ce besoin et ils ont développé pour nous, deux nouveaux espaces de nom qui facilitent l'envoi de mail. Ces deux espaces de noms sont System.Net.Mail et System.Net.Mime qui permettent respectivement, de créer un objet Mail (MailMessage) et de gérer les entêtes MIME des mails.
Commençons donc par créer l'objet représentant notre mail:
Création de l’objet représentant le mail MailMessage monMail;
Cette classe contient un nombre conséquent de propriétés permettant de personnaliser le mail comme vous le feriez avec votre client de messagerie. Commençons par définir l’auteur du mail. Ceci se réalise à l’aide de la classe MailAdress.
Ajout de l’auteur du mail monMail.From = new MailAddress("modd_hay@hotmail.com");
La deuxième chose à définir sont le(ou les) destinataire(s).
Ajout de destinataires // ajout de deux destinataires principauxmonMail.To.Add(new MailAddress("modd_hay@hotmail.com "));monMail.To.Add(new MailAddress("modd_hay@hotmail.com ")); // ajout d’un destinataire CCmonMail.Cc.Add(new MailAddress("modd_hay@hotmail.com ")); // ajout d’un destinataire CCImonMail.CCi.Add(new MailAddress("modd_hay@hotmail.com "));
Comme vous le voyez, il est très facile de spécifier les destinataires du mail et surtout d’en définir plusieurs tout en spécifiant à quel groupe de réception ils appartiennent.
Spécifions maintenant le sujet(titre) du mail ainsi que son contenu
Ajout du sujet et du contenu monMail.Subject = "Mail de test";monMail.Body = "Hello les gens";
Votre mail est alors prêt à être envoyé: ce que nous allons faire tout de suite. Créeons un objet SMTPClient et configurons le:
Création/Personnalisation du SMTPClient // création du SMTPClientSmtpClient client = new SmtpClient(); // définition du serveur smtpclient.Host = "smtp.developpez.com"; // définition des login et pwd si smtp sécuriséclient.Credentials = new NetworkCredential("pharaonix", "mon mot de passe");
Il ne nous reste plus qu’une chose à faire: envoyer le mail.
Envoi du mail client.Send(monMail);
Je vous avais promis précédemment qu’il était possible d’inclure des pièces jointes à vos mails. vous allez constater que leur utilisation est tout aussi simple. Chaque pièce jointe est représentée par un objet Attachment
Pièces jointes // création de la pièce jointeAttachment maPieceJointe = new Attachment(@"c:/fichier.zip"); // chemin de la pièce jointe // ajout de la pièce jointe au mailmonMail.Attachments.Add(maPieceJointe); /*// suppression de la pièce jointemonMail.Attachments.RemoveAt(0);*/
Vous ne pouvez qu’admirer le travail fait par les développeurs Microsoft et apprécier la facilité avec laquelle vous pourrez dorénavant envoyer n’importe quel type de mail dans vos applications .Net

II - Réception de mail

Je n’ai pas trouvé sur la MSDN de classe spécifique pour la réception de mail, mais il existe des composants tiers sur le net (payants) qui proposent des classes facilitant cette tâche. Nous allons voir comment se passer de ces classes tierces et comment recevoir les mails le plus simplement possible.
La récupération de mail en POP3 se fait à l’aide d’une communication client/serveur. En effet, le client(logiciel de messagerie) et le serveur s’envoient une suite bien définie de commandes et/ou de réponses correspondantes.

Qui Action Client connexion avec le socket Serveur +OK connected to pop3 Client USER pharaonix Serveur +OK name is a valid mailbox Client PASS mon_mot_de_passe Serveur +OK user exist with that password Client STAT Serveur +OK [Nombre de Messages] [Taille] Client RETR [Numero Du Mail] Serveur +OK Données du mail (entête+contenu) Client QUIT Serveur +OK
Notez que j’indique le serveur renvoie "+OK" ainsi qu’un message de réponse. Dans le cas d’une erreur, le serveur renverra "-ERR" et un message de réponse. Toutes ces commandes, ce fonctionnement, cette nomenclature de messages, sont définis dans la norme rfc1939 ou la norme rfc1725.
Et dans la pratique? Et bien, nous allons devoir suivre ces étapes une par une.
II-1 Connexion
Commençons par nous connecter au serveur:
private TcpClient monSocket;monSocket = new TcpClient("pop.developpez.com", 110); // 110 est le port par défaut pour les serveurs POP3
La communication client/serveur se fera à l’aide d’un flux (stream):
private NetworkStream monStream;
Nous initialisons notre Stream à l’aide du stream de notre socket. Profitons en pour créer un objet StreamReader qui nous permettra de lire le contenu de notre Stream, tout du long de la communication avec le serveur POP3. C’est dans ce dernier que nous recevrons les messages de réponse du serveur ainsi que les mails.
// initialisation du StreammonStream = monSocket.GetStream(); // création du streamreaderprivate StreamReader monStreamReader;monStreamReader = new StreamReader(monStream);
Maintenant que nous avons une "connexion" avec le serveur, nous allons nous y authentifier. Nous allons préparer les commandes et les envoyer au serveur.
// Préparation de la commande USER avec le nom d’utilisateurString Commande = "user " + _Login + "\r\n"; // Envoi de la commande au serveurByte[] bCommande = System.Text.ASCIIEncoding.ASCII.GetBytes(Commande);monStream.Write(bCommande, 0, bCommande.Length);
Lorsque nous nous sommes connecté au serveur, celui nous a renvoyé la réponse suivante: "+OK connected to pop3 on 1012", puis nous lui avons envoyé la commande USER à laquelle il a répondu (car l’utilisateur existe vraiment): +OK name is a valid mailbox. L’étape suivante consiste à envoyer le mot de passe du compte pour être reconnu et authentifié sur le serveur:
// Préparation de la commande PASS avec le mot de passe utilisateurString Commande = "pass " + _Pwd + "\r\n"; // Envoi de la commande au serveurByte[] bCommande = System.Text.ASCIIEncoding.ASCII.GetBytes(Commande);monStream.Write(bCommande, 0, bCommande.Length);
Si le login et surtout le mot de passe sont corrects, alors vous recevrez le message: "+OK user exist with that password". Vous pouvez dorénavant travailler comme bon vous semble avec le serveur.
RéceptionNous allons maintenant aborder la réception des mails. Celle-ci se fait en deux principales étapes. La première consiste à demander au serveur s’il contient des mails. Nous pouvons la réaliser à l’aide de la commande STAT, puis nous parserons la réponse du serveur
/// /// Récupère le nombre de mails sur le serveur, en parsant la réponse du serveur du type "+OK Nbre Taille"/// /// /// /// private int NombreDeMessages(int mode, params int[] index){ String sOutStream = ""; if (mode == 1) sOutStream = "stat\r\n"; else if (mode == 2) sOutStream = "list " + index[0].ToString() + "\r\n"; String[] tempS ={ "0" }; try { EnvoiCommande(sOutStream); String tempLog = sr.ReadLine(); tempS = tempLog.Split(‘ ‘); } catch (Exception e) { MessageBox.Show("erreur" + e); } return int.Parse(tempS[1]);}
La méthode précédente nous renvoyait donc le nombre de mails qui se trouvent sur le serveur et la taille totale prise par ceux-ci, puis nous la parsions pour ne récupérer que le nombre de mails
Avant de démarrer, il faut bien prendre en compte le fait suivant : le traitement de réception peut être assez complexe, pour les raisons suivantes : - même s’il existe des normes, tous les mails ne les respectent pas forcément, - les possibilités de contenu d’un mail sont très vastes. Ne vous étonnez donc pas que votre réception de mail ne soit pas aussi parfaite que celle d’un client de messagerie comme Microsoft Outlook ou Thunderbird.
Dans cette partie, je vais donc vous présenter une manière simple de récupérer les mails et les informations associées. Il serait bien entendu possible de développer cette approche d’une manière beaucoup plus exhaustive, mais ce n’est pas le but de cette présentation.
Nous allons maintenant recevoir les mails. Cela ne se fait qu’en les recevant un par un, en les "appelant" par leur numéro.