18 votos

Cómo enviar un correo electrónico con datos adjuntos mediante SmtpClient.SendAsync?

Estoy utilizando un componente de servicio a través de ASP.NET MVC. Me gustaría enviar el correo electrónico en un asincrónica manera para que el usuario pueda hacer otras cosas sin tener que esperar el envío.

Cuando me envían un mensaje sin archivos adjuntos funciona bien. Al enviar un mensaje con al menos uno de ellos en-memoria apego se produce un error.

Así que, me gustaría saber si es posible utilizar un método asincrónico con en-memoria anexos.

Aquí es el método de envío


    public static void Send() {

    	MailMessage message = new MailMessage("from@foo.com", "too@foo.com");
    	using (MemoryStream stream = new MemoryStream(new byte[64000])) {
    		Attachment attachment = new Attachment(stream, "my attachment");
    		message.Attachments.Add(attachment);
    		message.Body = "This is an async test.";

    		SmtpClient smtp = new SmtpClient("localhost");
    		smtp.Credentials = new NetworkCredential("foo", "bar");
    		smtp.SendAsync(message, null);
    	}
    }

Aquí está mi error


System.Net.Mail.SmtpException: Failure sending mail.
 ---> System.NotSupportedException: Stream does not support reading.
   at System.Net.Mime.MimeBasePart.EndSend(IAsyncResult asyncResult)
   at System.Net.Mail.Message.EndSend(IAsyncResult asyncResult)
   at System.Net.Mail.SmtpClient.SendMessageCallback(IAsyncResult result)
   --- End of inner exception stack trace ---


Solución

    public static void Send()
    {

            MailMessage message = new MailMessage("from@foo.com", "to@foo.com");
            MemoryStream stream = new MemoryStream(new byte[64000]);
            Attachment attachment = new Attachment(stream, "my attachment");
            message.Attachments.Add(attachment);
            message.Body = "This is an async test.";
            SmtpClient smtp = new SmtpClient("localhost");
            //smtp.Credentials = new NetworkCredential("login", "password");

            smtp.SendCompleted += delegate(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
            {
                    if (e.Error != null)
                    {
                            System.Diagnostics.Trace.TraceError(e.Error.ToString());

                    }
                    MailMessage userMessage = e.UserState as MailMessage;
                    if (userMessage != null)
                    {
                            userMessage.Dispose();
                    }
            };

            smtp.SendAsync(message, message);
    }

19voto

liggett78 Puntos 8268

No use "el uso de" aquí. Están destruyendo la secuencia de memoria inmediatamente después de llamar a SendAsync, por ejemplo, probablemente antes de SMTP llega a leer (ya que es asíncrono). Destruir su secuencia en la devolución de llamada.

0voto

Robert Vuković Puntos 2670

He tratado de su función y funciona incluso por correo electrónico en la memoria de archivos adjuntos. Pero aquí hay algunas observaciones:

  • ¿Qué tipo de archivos adjuntos hizo intenta enviar ? Exe ?
  • Son el remitente y el receptor en el mismo servidor de correo electrónico ?
  • Usted debe "capturar" la excepción y no sólo se lo trague, que se podrá obtener más información acerca de tu problema.
  • ¿Qué hace la excepción dice ?

  • Funciona whan utilizar Enviar en lugar de SendAsync ? Usted está utilizando " con " cláusula de cierre de la Secuencia antes de que se envía el correo electrónico.

Aquí es un buen texto sobre este tema:

El envío de Correo electrónico .NET 2.0

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by: