2008-08-26 22 views
15

Je dois envoyer des centaines de bulletins d'information, mais je voudrais d'abord vérifier si l'email existe sur le serveur. C'est ce qu'on appelle la validation SMTP, du moins je le pense, d'après mes recherches sur Internet.Email validateur SMTP

Il y a plusieurs bibliothèques qui peuvent le faire, et aussi une page avec du code open-source dans ASP Classic (http://www.coveryourasp.com/ValidateEmail.asp#Result3), mais j'ai du mal à lire ASP Classic, et il semble qu'il utilise une bibliothèque tierce ...

y at-il un code de validation SMTP en C# et/ou explication générale de la façon dont cela fonctionne?

Répondre

19

Soyez conscient que la plupart des MTA (Mail Agent de transfert) aura la commande VRFY désactivée pour des raisons de protection contre le spam, ils vous bloqueront probablement même si vous essayez plusieurs RCPT TO à la suite (voir http://www.spamresource.com/2007/01/whatever-happened-to-vrfy.html). Donc, même si vous trouvez une bibliothèque pour faire cette vérification, cela ne vaudra pas beaucoup. Ishmaeel a raison, la seule façon de le savoir est d'envoyer un email et de voir s'il rebondit ou non.

@Hrvoje: Oui, je vous suggère de surveiller les courriels rejetés. MAIS: tous les mails rebondis ne devraient pas automatiquement se retrouver sur votre liste "n'existe pas", vous devez également faire la différence entre les erreurs temporaires (par exemple la boîte aux lettres pleine) et permanentes.

1

Le Real (TM) validation e-mail tente d'envoyer quelque chose à l'adresse, et voir si elle est rejetée/rebondissait. Ainsi, vous devrez simplement les renvoyer et supprimer les adresses qui échouent de votre liste de diffusion. SMTP est un protocole basé sur le texte transporté sur TCP/IP.

+0

Ce n'est pas vrai – User

8

Votre programme de validation doit ouvrir une connexion TCP/IP au port 25 (SMTP) du serveur, écrire en quelques lignes et lire la réponse. La validation est effectuée (mais pas toujours) sur la ligne "RCTP TO" et sur la ligne "VFRY".

Le SMTP RFC décrit comment cela fonctionne (voir ci-dessous [email protected], S sont des lignes envoyées par le client, R sont des lignes reçues du serveur):

 
Example of the SMTP Procedure 

     This SMTP example shows mail sent by Smith at host Alpha.ARPA, 
     to Jones, Green, and Brown at host Beta.ARPA. Here we assume 
     that host Alpha contacts host Beta directly. 

      S: MAIL FROM: 
      R: 250 OK 

      S: RCPT TO: 
      R: 250 OK 

      S: RCPT TO: 
      R: 550 No such user here 
2

Ne le prenez pas mal, mais l'envoi de lettres d'information à plus d'une poignée de personnes ces jours-ci est une question assez grave. Oui, vous devez surveiller les rebonds (e-mails rejetés) qui peuvent se produire de manière synchrone pendant l'envoi SMTP (généralement si le serveur SMTP auquel vous êtes connecté fait autorité), ou asynchrone comme un message électronique généré par le système l'envoi SMTP a réussi.

garder aussi la loi CAN-SPAM à l'esprit et respecter la loi lors de l'envoi de ces e-mails; Vous devez fournir un lien de désinscription ainsi qu'une adresse physique (pour vous identifier et permettre aux utilisateurs d'envoyer des demandes d'identification par courrier électronique s'ils le souhaitent).

Le non-respect de ces choses pourrait obtenir votre routé IP nulle au mieux et poursuivi au pire.

4

S'il est vrai que de nombreux domaines renverront des faux positifs en raison d'abus, il existe néanmoins de bons composants qui effectueront plusieurs niveaux de validation au-delà de la simple validation SMTP. Par exemple, cela vaut la peine de vérifier d'abord si au moins le domaine existe.Je suis en train de compiler ma propre liste des ressources liées à cette question que vous pouvez suivre ici:

http://delicious.com/dworthley/email.validation

Pour ceux qui pourraient vouloir ajouter à cette liste, je rajouterais aussi ce que je actuellement voir ici:

Pour une forme pare-balles et une grande expérience utilisateur, il est utile de valider autant d'aspects de l'adresse e-mail que possible. Je peux voir de la aspNetMX validateur qu'ils vérifient:

  • la syntaxe
  • l'e-mail à une liste d'adresses e-mail mauvais
  • le domaine à une liste de mauvais domaines
  • une liste de domaines de boîte aux lettres
  • si oui ou non le domaine existe
  • s'il y a des enregistrements MX pour le domaine
  • et enfin par SMTP que v r ou non une boîte aux lettres existe

Il est cette dernière étape qui peut être contournée par les administrateurs en retournant vrai essentiellement toutes les demandes de vérification des comptes, mais dans la plupart des cas, si l'utilisateur a volontairement entré une mauvaise adresse, il a déjà été pris. Et s'il s'agissait d'une erreur de l'utilisateur dans la partie domaine de l'adresse, celle-ci sera également interceptée. Bien sûr, une bonne pratique pour utiliser ce type de service pour un écran ou un formulaire d'inscription serait de combiner ce type de validation avec un processus de vérification pour s'assurer que l'adresse e-mail est valide. La grande chose à propos de l'utilisation d'un validateur d'email en amont d'un processus de vérification est que cela améliorera l'expérience utilisateur globale.

+0

aspNetMX semble à portée de main, mais je souhaite que ce n'était pas .NET – User

1

Vous devrez peut-être ce Email Validator component for .NET

Voici l'exemple de code:


    // Create a new instance of the EmailValidator class. 
    EmailValidator em = new EmailValidator(); 
    em.MessageLogging += em_MessageLogging; 
    em.EmailValidated += em_EmailValidationCompleted; 
    try 
    { 
     string[] list = new string[3] { "[email protected]", "[email protected]", "[email protected]" }; 
     em.ValidateEmails(list); 
    } 
    catch (EmailValidatorException exc2) 
    { 
     Console.WriteLine("EmailValidatorException: " + exc2.Message); 
    } 
+0

je veux open source, version gratuite, mais de toute façon –

3

Vous pouvez essayer le code ci-dessous, il fonctionne très bien pour moi:

public class EmailTest { 
    private static int hear(BufferedReader in) throws IOException { 
     String line = null; 
     int res = 0; 

     while ((line = in.readLine()) != null) { 
      String pfx = line.substring(0, 3); 
      try { 
       res = Integer.parseInt(pfx); 
      } catch (Exception ex) { 
       res = -1; 
      } 
      if (line.charAt(3) != '-') 
       break; 
     } 

     return res; 
    } 

    private static void say(BufferedWriter wr, String text) throws IOException { 
     wr.write(text + "\r\n"); 
     wr.flush(); 

     return; 
    } 

    @SuppressWarnings({ "rawtypes", "unchecked" }) 
    private static ArrayList getMX(String hostName) throws NamingException { 
     // Perform a DNS lookup for MX records in the domain 
     Hashtable env = new Hashtable(); 
     env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory"); 
     DirContext ictx = new InitialDirContext(env); 
     Attributes attrs = ictx.getAttributes(hostName, new String[] { "MX" }); 
     Attribute attr = attrs.get("MX"); 

     // if we don't have an MX record, try the machine itself 
     if ((attr == null) || (attr.size() == 0)) { 
      attrs = ictx.getAttributes(hostName, new String[] { "A" }); 
      attr = attrs.get("A"); 
      if (attr == null) 
       throw new NamingException("No match for name '" + hostName + "'"); 
     } 
     /* 
     Huzzah! we have machines to try. Return them as an array list 
     NOTE: We SHOULD take the preference into account to be absolutely 
     correct. This is left as an exercise for anyone who cares. 
     */ 
     ArrayList res = new ArrayList(); 
     NamingEnumeration en = attr.getAll(); 

     while (en.hasMore()) { 
      String mailhost; 
      String x = (String) en.next(); 
      String f[] = x.split(" "); 
      // THE fix ************* 
      if (f.length == 1) 
       mailhost = f[0]; 
      else if (f[1].endsWith(".")) 
       mailhost = f[1].substring(0, (f[1].length() - 1)); 
      else 
       mailhost = f[1]; 
      // THE fix ************* 
      res.add(mailhost); 
     } 
     return res; 
    } 

    @SuppressWarnings("rawtypes") 
    public static boolean isAddressValid(String address) { 
     // Find the separator for the domain name 
     int pos = address.indexOf('@'); 

     // If the address does not contain an '@', it's not valid 
     if (pos == -1) 
      return false; 

     // Isolate the domain/machine name and get a list of mail exchangers 
     String domain = address.substring(++pos); 
     ArrayList mxList = null; 
     try { 
      mxList = getMX(domain); 
     } catch (NamingException ex) { 
      return false; 
     } 

     /* 
     Just because we can send mail to the domain, doesn't mean that the 
     address is valid, but if we can't, it's a sure sign that it isn't 
     */ 
     if (mxList.size() == 0) 
      return false; 

     /* 
     Now, do the SMTP validation, try each mail exchanger until we get 
     a positive acceptance. It *MAY* be possible for one MX to allow 
     a message [store and forwarder for example] and another [like 
     the actual mail server] to reject it. This is why we REALLY ought 
     to take the preference into account. 
     */ 
     for (int mx = 0; mx < mxList.size(); mx++) { 
      boolean valid = false; 
      try { 
       int res; 
       // 
       Socket skt = new Socket((String) mxList.get(mx), 25); 
       BufferedReader rdr = new BufferedReader(new InputStreamReader(skt.getInputStream())); 
       BufferedWriter wtr = new BufferedWriter(new OutputStreamWriter(skt.getOutputStream())); 

       res = hear(rdr); 
       if (res != 220) 
        throw new Exception("Invalid header"); 
       say(wtr, "EHLO rgagnon.com"); 

       res = hear(rdr); 
       if (res != 250) 
        throw new Exception("Not ESMTP"); 

       // validate the sender address 
       say(wtr, "MAIL FROM: <[email protected]>"); 
       res = hear(rdr); 
       if (res != 250) 
        throw new Exception("Sender rejected"); 

       say(wtr, "RCPT TO: <" + address + ">"); 
       res = hear(rdr); 

       // be polite 
       say(wtr, "RSET"); 
       hear(rdr); 
       say(wtr, "QUIT"); 
       hear(rdr); 
       if (res != 250) 
        throw new Exception("Address is not valid!"); 

       valid = true; 
       rdr.close(); 
       wtr.close(); 
       skt.close(); 
      } catch (Exception ex) { 
       // Do nothing but try next host 
       ex.printStackTrace(); 
      } finally { 
       if (valid) 
        return true; 
      } 
     } 
     return false; 
    } 

    public static void main(String args[]) { 
     String testData[] = { "[email protected]", "[email protected]", "[email protected]", 
     "[email protected]" }; 
     System.out.println(testData.length); 
     for (int ctr = 0; ctr < testData.length; ctr++) { 
      System.out.println(testData[ctr] + " is valid? " + isAddressValid(testData[ctr])); 
     } 
     return; 
    } 
} 

Merci & Cordialement Rahul Saraswat

+0

un serveur web jamais bloquer mon adresse IP si je vérifie adresses e-mail illimitées? – desaiankitb

+0

Seulement obtenir "en-tête invalide" pour toutes les adresses e-mail :-( –