Cliente SMTP light C#


Aunque hay mucha información sobre esto, quiero hacer mi parte.

En C#, hay una manera muy fácil de enviar un correo, con archivos adjuntos y contenido HTML (si se quiere).

.Net desde el framework 2.0 nos ofrece en el namespace System.Net.Mail, varias clases que no son útiles para enviar correos.

Entre esas tenemos:

  • Attachment: Es la clase encargada de manejar nuestros archivos adjuntos
  • MailAddress: Esta clase representa la dirección de la persona a la que le vamos a enviar el correo
  • MailMessage: Es la clase que representa el mensaje del correo, en esta clase definimos: quién lo envía, para quién, Asunto, Cuerpo del mensaje, entre otras.
  • SmtpClient: Con esta clase podemos enviar los correos mediante el protocolo SMTP (Protocolo Simple de Transferencia de Correo).

Para explicar todo, vamos a hacer una aplicación en WPF, aunque la pueden usar en Windows Forms o en ASP.Net, la aplicación será un pequeño cliente, donde ingresaremos direcciones para enviar, y podrémos adjuntar archivos, y otras cosas. Para ver nuestro pequeño cliente en funcionamiento, voy a hacer uso del SmtpClient de Gmail, por lo que tendremos que tener una cuenta de Gmail.

La interfaz de la aplicación en Windows Presentation Foundation (WPF)es la siguiente, aunque ustedes pueden cambiarlo como quieran:

 Interfaz

Lo primero que se hace es crear un objeto MailMessage, luego para obtener las direcciones a las cuales vamos a enviar el correo, hacemos un Split al Texto, para obtener las direcciones separadas por comas (,).

Agregamos la dirección de la cuál estamos enviando el correo, el asunto y el cuerpo del Mensaje:

MailMessage mailmsg = new MailMessage();
String[] direcciones = txtPara.Text.Split(',');
foreach (string dire in direcciones)
{
  mailmsg.To.Add(dire);
}
mailmsg.From = new MailAddress(txtde.Text,"Martín");
mailmsg.Subject = txtAsunto.Text;
mailmsg.Body = txtCuerpo.Text;

En la opción de From, adicioné el nombre para mostrar en el destino.

Para adjuntar archivos creamos un OpenFileDialog para obtener recursos de nuestro disco, modificamos el OpenFileDialog para que permita escoger múltiples archivos al tiempo, y guardamos estos archivos en una variable Global:

List<String> filePath = null;
public Window1()
{
  InitializeComponent();
  filePath = new List<String>();
}

El código del botón es el siguiente:

private void button1_Click(object sender, RoutedEventArgs e)
{
  OpenFileDialog file = new OpenFileDialog();
  file.Multiselect = true;
  String[] nombresArchivos = null;

  if (file.ShowDialog() == true)
  {
    nombresArchivos = file.SafeFileNames;
    filePath.AddRange(file.FileNames);
  }
  foreach (string adjunto in nombresArchivos)
  {
    txtAdjuntos.Text += adjunto + ",";
  }
}

En el código del botón enviar, debemos adicionar los archivos adjuntos, el código quedaría así:

MailMessage mailmsg = new MailMessage();
String[] direcciones = txtPara.Text.Split(',');
foreach (string dire in direcciones)
{
  mailmsg.To.Add(dire);
}

mailmsg.From = new MailAddress(txtde.Text, "Martín");
mailmsg.Subject = txtAsunto.Text;
mailmsg.Body = txtCuerpo.Text;
mailmsg.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure;
if (filePath != null)
{
  for (int i = 0; i < filePath.Count; i++)
  {
     mailmsg.Attachments.Add(new Attachment(filePath[i]));
  }
}

Después de haber configurado nuestra clase MailMessage, podemos crear un objeto SmtpClient y enviar el correo:

SmtpClient cliente = new SmtpClient("localserver");
cliente.Send(mailmsg);

Pero para crear el SmtpClient debemos tener un servidor Smtp, para ahorrarnos la tarea, vamos a hacer uso del Servidor de Gmail, seguimos con nuestro código:

SmtpClient  cliente = new SmtpClient("smtp.gmail.com", 587);
cliente.EnableSsl = true ;
NetworkCredential myCreds = new NetworkCredential("user@gmail.com", "password" );
cliente.Credentials = myCreds;
try
{
  cliente.Send(mailmsg);
}
catch (Exception  ex)
{
  MessageBox.Show(ex.Message);
}

Bien, ahora si probamos enviando unos correos a mis cuentas veremos:

enviocorreo

En Hotmail:

hotmail

En Gmail:

Gmail

Cuando ocurre un error, el error es notificado en nuestra bandeja de entrada de Gmail.

Si se dieron cuenta, al enviar los correos, la aplicación no responde, para evitar eso podemos hacer uso de los métodos asincrónicos:

cliente.SendAsync(mailmsg,”text”);

Bueno, queda mucho por investigar 😛 pero yo ya tengo sueño, así que queda para ustedes seguir profundizando en este tema.

Referencias:

MSDN

Blog de Mariya Atanasova

Código Fuente:

Aquí

Anuncios

22 pensamientos en “Cliente SMTP light C#

  1. 01 MailMessage mailmsg = new MailMessage();
    02
    03 String[] direcciones = txtPara.Text.Split(‘,’);
    04
    05 foreach (string dire in direcciones)
    06
    07 {
    08
    09 mailmsg.To.Add(dire);
    10
    11 }
    12
    13 mailmsg.From = new MailAddress(txtde.Text,”Martín”);
    14
    15 mailmsg.Subject = txtAsunto.Text;
    16
    17 mailmsg.Body = txtCuerpo.Text;
    NO ME QUEDO CLARO EN DONDE VA ESE CODIGO EN DONDE VA SALUDOS?

    • Hola, eso va en el código del clic del botón Enviar, en esa porción de código se configuran las direcciones a donde se va a enviar el correo, el Asunto y el cuerpo, también la dirección desde la cual se envía.
      Después de esto se debe hacer el cliente.Send(mailmsg) usando el servidor de correos preferido

  2. me vino otra duda aca por ejemplo
    13 mailmsg.From = new MailAddress(txtde.Text,”Martín”);
    ese nombre entre ” es necesario ponerlo ?” o solo con txtde.Text al escribe en el txtde te va a decir de quien es ?
    SmtpClient cliente = new SmtpClient(“smtp.gmail.com”, 587);
    02
    03 cliente.EnableSsl = true ;
    04
    05 NetworkCredential myCreds = new NetworkCredential(“user@gmail.com”, “password” );
    y esto para que se @hotmail y gmail como seria?osea que se pueda enviar a los 2

    • Hola, la clase MailAddress tiene 3 constructores, uno recibe como parámetro la dirección de correo, y otro recibe la dirección de correo y un nombre que será utilizado para asociarlo a la dirección de correo, sino lo escribes no se va a mostrar el nombre de la persona, a menos que ya se tenga configurado en los contactos del correo destino.
      El código del smtpClient es para usar el servidor de correos de Gmail, pero si ves en el ejemplo, se envió un correo a Hotmail y Gmail. El SmtpClient se configura para que puedas enviar los correos desde la aplicación.

  3. private void adjuntar_Click(object sender, EventArgs e)
    {
    OpenFileDialog file = new OpenFileDialog();
    file.Multiselect = true;
    String[] nombresArchivos = null;
    if (file.ShowDialog() == true) aca me dice este error El operador ‘==’ no se puede aplicar a operandos del tipo ‘System.Windows.Forms.DialogResult’ y ‘bool’
    {
    nombresArchivos = file.SafeFileNames;
    filePath = file.FileNames; ya aca El nombre ‘filePath’ no existe en el contexto actual
    }
    me dice esos errores me podria ayudar ?

    • Hola, el primer error es posible debido a que el programa que hice lo hice bajo WPF y tú lo estas haciendo con Windows forms, si es así solo cambia el true por System.Windows.Forms.DialogResult.OK.
      Para el segundo error, debes declarar una varialble global o justo antes de la declaración del form o de la clase:
      String[] filePath = null;
      Puedes descargar el código fuente y verlo en acción en WPF

      • cuando le doy en enviar correo me dice esto
        cliente.Send(mailmsg); no se controlo SmtpExeption que puede estar pasando ?

      • Hola, En la propiedad InnerException de la Excepción que te sale?, Modificaste la NetworkCredential con un usuario real de Gmail o estas usando un servidor de correo diferente?

  4. probe tu codigo para adjuntar archivos y enviarlos y si envia el correo pero los archivos no los envia, se supone que para enviar archivos adjuntos tenes que capturar la ruta donde se encuentra el archivo esto lo haces en tu codigo

    • Hola, primero debes saber si la empresa desde donde se va a enviar el correo, tiene un servidor de correos, luego con el nombre del servidor o la ip se configura en la siguiente línea:

      SmtpClient cliente = new SmtpClient(“ipservidorcorreo”, puerto);
      cliente.Send(mailmsg);

      También debes tener en cuenta, si se necesitan credenciales para poder enviar el correo o no.
      Luego solo llenas los campos necesarios: para quién es el correo, el asunto, el correo de quién lo envía, el cuerpo del mensaje y los adjuntos.

      • oye pero por ejemplo puedo enviar a muchos destinatarios como hotmail.com,gmail,yahoo,myclub,etc

      • Claro, desde que el correo sea valido se puede enviar a cualquier correo, en el código se agregan las direcciones en la siguiente línea:

        mailmsg.To.Add(dire);
        Donde dire es un correo

  5. Hola Martin Reina mira ya puedo enviar correos electronicos desde mi aplicacion muchas gracuas, pero ahora tengo un pequeño inconveniente ..necesito que estos correos sea enviados al administrador treinta dias antes de que se venza un contraato de forma automatica

    • Hola, para hacer lo que quieres, puedes crear una tarea programada de Windows que ejecute la aplicación y este verificando si la de vencimiento del contrato menos 30 días es igual a la fecha actual, si es así, invocas el código que envía el correo.

      • Claro me parece una buena idea, en mi caso comparaba la fecha del sistema, con la del campo de la BD, si lo hace solo que en la consulta pueden existir varios contratos que venzan el mismo dia y en el bucle solo manda el correo al ultimo registro y ahora ya no se como hacerle

  6. Mira cambie los textbox por un datagrid donde realizo la consulta y llamo todos los datos
    String Consulta = “select * from TbRegDom where FV between now() and now() + interval 30 day”;
    ConexionMySQl Ejecuta = new ConexionMySQl();
    Ejecuta.AbrirConexion();
    if (Ejecuta.Conectado == true)
    {
    DataSet DatoTabla = new DataSet();
    DatoTabla = Ejecuta.Consultas(Consulta);
    DataGridEnviarCorreo.DataSource = DatoTabla.Tables[“MiTabla”];
    DataGridEnviarCorreo.Columns[0].Visible=false;//.HeaderText = “Número”;
    DataGridEnviarCorreo.Columns[1].HeaderText = “Dominio”;
    DataGridEnviarCorreo.Columns[2].HeaderText = “Cliente”;
    DataGridEnviarCorreo.Columns[3].Visible=false;//.HeaderText = “Contrato”;
    DataGridEnviarCorreo.Columns[4].HeaderText = “Vencimiento”;
    DataGridEnviarCorreo.Columns[5].Visible = false;//.HeaderText = “Paquete”;
    DataGridEnviarCorreo.Columns[6].Visible = false;//.HeaderText = “Correos adicionales”;
    DataGridEnviarCorreo.Columns[7].Visible = false;//.HeaderText = “VMS-ID”;
    DataGridEnviarCorreo.Columns[8].Visible = false;//.HeaderText = “Espacio en disco”;
    DataGridEnviarCorreo.Columns[9].Visible = false;//.HeaderText = “Contrato Hosting”;
    DataGridEnviarCorreo.Columns[10].Visible = false;//.HeaderText = “Vencimiento Hosting”;
    y despues recorro los datos en un bucle Int32 i;
    String celda;
    DataGridViewCell dgc;
    for (i = 0; i < DataGridEnviarCorreo.Rows.Count; i++)
    {
    dgc = DataGridEnviarCorreo.Rows[i].Cells[1];
    celda = ((String)dgc.Value) + "\r\n";
    txtdominio.Text += celda.Replace(".",",");
    }

    y el metodo que realizo de enviar correo lo llamo en el load hasta ahorita el problema es que no considero que mientras se este ejecutando la aplicacion lo va estar enviando

Deseas comentar o sugerir algo?

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s