Pregunta

Necesito enviar cientos de boletines, pero primero me gustaría comprobar si existe un correo electrónico en el servidor.Se llama SMTP validación, al menos eso creo, basado en mi investigación en Internet.

Hay varias bibliotecas que pueden hacer eso, y también una página con código fuente abierto en ASP clásico (http://www.coveryourasp.com/ValidateEmail.asp#Result3), pero me cuesta leer ASP Classic y parece que utiliza alguna biblioteca de terceros...

¿Existe algún código para la validación SMTP en C# y/o una explicación general de cómo funciona?

¿Fue útil?

Solución

Tenga en cuenta que la mayoría de los MTA (Agente de transferencia de correo) tendrán el comando VRFY desactivado por motivos de protección contra spam; probablemente incluso lo bloquearán si prueba varios RCPT TO seguidos (consulte http://www.spamresource.com/2007/01/whatever-happened-to-vrfy.html).Entonces, incluso si encuentra una biblioteca para realizar esa verificación, no valdrá mucho.Ismaeel tiene razón, la única forma de saberlo realmente es enviando un correo electrónico y ver si rebota o no.

@Hrvoje:Sí, te sugiero que supervises los correos electrónicos rechazados.PERO:No todos los correos rebotados deberían terminar automáticamente en su lista "no existe", también debe diferenciar entre mensajes temporales (p. ej.buzón lleno) y errores permanentes.

Otros consejos

SMTP es un protocolo basado en texto transmitido a través de TCP/IP.

Su programa de validación necesita abrir una conexión TCP/IP al puerto 25 del servidor (SMTP), escribir unas pocas líneas y leer la respuesta.La validación se realiza (pero no siempre) en la línea "RCTP TO" y en la línea "VFRY".

El RFC SMTP describe cómo funciona esto (consulte Green@Beta.ARPA a continuación, S son líneas enviadas por el cliente, R son líneas recibidas del servidor):

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

Si bien es cierto que muchos dominios arrojarán falsos positivos debido al abuso, todavía existen algunos componentes excelentes que realizarán varios niveles de validación más allá de la validación SMTP.Por ejemplo, vale la pena comprobar primero si al menos el dominio existe.Estoy en el proceso de compilar mi propia lista de recursos relacionados con esta pregunta, que puedes rastrear aquí:

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

Para aquellos que quieran agregar algo a esta lista, también incluiré lo que tengo actualmente aquí:

Para obtener un formulario a prueba de balas y una excelente experiencia de usuario, es útil validar tantos aspectos de la dirección de correo electrónico como sea posible.puedo ver desde el aspNetMX validador que verifican:

  • la sintaxis
  • el correo electrónico contra una lista de direcciones de correo electrónico incorrectas
  • el dominio frente a una lista de dominios malos
  • una lista de dominios de buzón
  • si el dominio existe o no
  • si hay registros MX para el dominio
  • y finalmente a través de SMTP exista o no un buzón

Es este último paso el que los administradores pueden eludir al devolver verdadero a básicamente todas las solicitudes de verificación de cuenta, pero en la mayoría de los casos, si el usuario ingresó intencionalmente una dirección incorrecta, ya ha sido detectado.Y si fue un error del usuario en la parte del dominio de la dirección, también se detectará.

Por supuesto, una mejor práctica para utilizar este tipo de servicio para una pantalla o formulario de registro sería combinar este tipo de validación con un proceso de verificación para garantizar que la dirección de correo electrónico sea válida.Lo mejor de utilizar un validador de correo electrónico antes de un proceso de verificación es que mejorará la experiencia general del usuario.

Puedes probar el siguiente código, funciona bien para mí:

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: <tim@orbaker.com>");
                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[] = { "rahul.saraswat@techblue.com", "rahul.saraswat@techblue.co.uk", "srswt.rahul12345@gmail.com",
        "srswt.rahul@gmail.com" };
        System.out.println(testData.length);
        for (int ctr = 0; ctr < testData.length; ctr++) {
            System.out.println(testData[ctr] + " is valid? " + isAddressValid(testData[ctr]));
        }
        return;
    }
}

Gracias y saludos Rahul Saraswat

La validación de correo electrónico de Real(TM) consiste en intentar enviar algo a la dirección y ver si es rechazado/rebotado.Por lo tanto, sólo tendrá que desecharlos y eliminar las direcciones que fallan de su lista de correo.

No lo tomes a mal, pero enviar boletines a más de un puñado de personas hoy en día es un asunto bastante serio.Sí, debe monitorear los rebotes (correos electrónicos rechazados) que pueden ocurrir de forma sincrónica durante el envío SMTP (generalmente si el servidor SMTP al que está conectado tiene autoridad) o de forma asincrónica como un mensaje de correo electrónico generado por el sistema que ocurre algún tiempo después. el envío SMTP fue exitoso.

También tenga en cuenta la Ley CAN-SPAM y respete la ley al enviar estos correos electrónicos;debe proporcionar un enlace para darse de baja, así como una dirección física (tanto para identificarlo como para permitir a los usuarios enviar solicitudes de baja por correo postal si así lo desean).

Si no se hacen estas cosas, su IP podría anularse en el mejor de los casos y, en el peor, ser demandada.

Puede que necesites esto Componente Validador de correo electrónico para .NET

Aquí está el ejemplo de código:


   // 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] { "test1@testdomain.com", "test2@testdomain.com", "test3@testdomain.com" };
       em.ValidateEmails(list);
   }
   catch (EmailValidatorException exc2)
   {
       Console.WriteLine("EmailValidatorException: " + exc2.Message);
   }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top