Header Ads Widget

Como enviar Emails desde C# (SMTP Client y MailKit)

enviar emails con c#Enviar emails (correos electrónicos) desde una aplicación no es lo que los desarrolladores de software, al menos en gran parte, consideramos una tarea divertida. Los emails son veteranos en el campo de la tecnología, y casi en todos los sistemas en los que he trabajado se ha requerido que el software envíe un mensaje de correo electrónico a un usuario.

Si bien, enviar emails, es aparentemente una tarea trivial, puede convertirse en un desafío si se toma cada aspecto en cuenta.

[embed]https://youtu.be/xsM5Owmf0cI[/embed]

¿Qué alternativas hay en C# para enviar emails?



  • Usar SMTP Client.

  • Usar MailKit.

  • Utilizar un proveedor de envío de email (AWS SES, Mandrill, SendGrid)


En los dos primeros casos utilizaremos librerías propias del .NET Framework (SMTP Client) o desarrolladas a partir del framework (MailKit). Eso involucra tener un servidor SMTP disponible para el envío de correos, adecuación del contenido y formato del mensaje de correo y otros cuidados a tener en cuenta. Fuera de eso, las dos primeras opciones no son tan escalables como la última, ya que el proveedor externo (externo a nuestra aplicación) tendrá diversas características especializadas en envío de correos masivos y formatos adecuados.

Sin embargo, en caso que la aplicación no envíe emails de forma masiva o con formatos no muy elaborados se pueden utilizar las dos primeras opciones.

Enviar emails con SMTPClient


El .NET Framework (y el Core) ya tienen el soporte para envío de emails integrado, a través del espacio de nombres System.Net.Mail. Usar SMTPClient es la opción más fácil de seguir, pero trae complicaciones técnicas: habría que tener un servidor SMTP instalado y configurado. Puedes decidirte a realizar esa tarea, disponer de un servidor (hablo del equipo físico), instalar un servidor SMTP, y configurarlo. Si no tienes idea y no hay tiempo, no te recomiendo que lo hagas, contrata a alguien que sepa hacerlo. 

Lo que se hace “normalmente”, para salvar el tema de tener un servidor propio, es utilizar un servidor SMTP que ya exista, gracias a Google tenemos el servidor SMTP de Gmail. Crea una cuenta nueva de Gmail, y esa será la que usaremos para el ejemplo.

Nota: para que puedas usar el servidor SMTP con tu cuenta de Gmail, debes acceder a la página de Seguridad, y habilitar el acceso a aplicaciones poco seguras (si esa opción no aparece, debes tener activada la opción de autenticación en dos pasos).

Para enviar un correo se necesita el siguiente código:
var smtpClient = new SmtpClient("smtp.gmail.com")

{

    Port = 587,

    Credentials = new NetworkCredential("email", "password"),

    EnableSsl = true,

};

    

smtpClient.Send("email", "recipient", "subject", "body");

En el ejemplo, se crea una instancia de SmtpClient, se configura de acuerdo a las opciones del servidor SMTP, y luego se procede a enviar el correo electrónico.

Otra opción es utilizar el objeto MailMessage para crear el mensaje y enviarlo.
var mailMessage = new MailMessage

{

    From = new MailAddress("email"),

    Subject = "subject",

    Body = "<h1>Hello</h1>",

    IsBodyHtml = true,

};

mailMessage.To.Add("recipient");

smtpClient.Send(mailMessage);

Gracias a MailMessage se tienen más opciones al formatear el correo, por ejemplo, la propiedad IsBodyHtml, que nos permite indicar que el mensaje tiene HTML incluido en el cuerpo del mensaje (propiedad Body).

Adjuntos


Cuando se envía correo electrónico, no se requiere solamente enviar el mensaje, sino adjuntar algún archivo adicional, esto se hace vía el objeto Attachment y MailMessage.

 
var mailMessage = new MailMessage

{

    ...

};

var attachment = new Attachment("profile.jpg", MediaTypeNames.Image.Jpeg);

mailMessage.Attachments.Add(attachment);

El archivo profile.jpg debe existir en una carpeta accesible por el programa.

Configuración de SMTP en config


Los ejemplos anteriores muestran el uso de SMTPClient, pero, la configuración del servidor SMTP no se coloca “en duro” en el programa, sino que debe ser “configurable”, sino sería una pesadilla si es que en algún momento cambia la configuración del servidor SMTP y estar reemplazando la versión de un software cada vez que ocurra tal cosa.

En .NET, la configuración de SMTP tiene su propia sección en el archivo config (app.config o web.config), donde se indican las opciones del servidor SMTP:
<mailSettings>
    <smtp deliveryMethod="Network">
      <network host="smtp.gmail.com" port="587" userName="email" password="password" enableSsl="true" />
    </smtp>
</mailSettings>

Cuando ya se tiene dicha configuración, basta crear una nueva instancia de SmtpClient para utilizarlo.
var smtpClient = new SmtpClient();

En .NET Core, no podemos hacerlo de la misma forma. Hay que declarar la configuración SMTP en appsettings.json:
{

  "Smtp": {

    "Host": "smtp.gmail.com",

    "Port": 587,

    "Username": "email",

    "Password": "password"

  }

}

Luego, se puede obtener la configuración de la siguiente forma:
var builder = new ConfigurationBuilder()

    .AddJsonFile("appsettings.json");

var config = builder.Build();

var smtpClient = new SmtpClient(config["Smtp:Host"])

{

    Port = int.Parse(config["Smtp:Port"]),

    Credentials = new NetworkCredential(config["Smtp:Username"], config["Smtp:Password"]),

    EnableSsl = true,

};

Enviar emails con MailKit


Ahora, las malas noticias. SMTPClient tiene una lápida y epitafio puesto por Microsoft. Sin ser tan extremistas, lo que dice Microsoft es que no recomienda su uso. Si vas a la documentación encontrarás una advertencia que dice que SMTPClient no se debe utilizar para nuevos desarrollos, ya que SMTPClient no soporta muchos protocolos modernos. Y recomienda utilizar MailKit.

Nota: Si bien debemos seguir las recomendaciones de Microsoft, antes de cambiar tu código que utiliza SMTPClient por MailKit, evalúa si es necesario, no es que SMTPClient no funcione, sólo que hay protocolos modernos que no soporta, y por ahora (febrero 2020), SMTPClient hace el trabajo y no es urgente el cambio.

MailKit es una librería .NET Open Source, que soporta IMAP, POP3, SMTP y muchos otros protocolos. Su interfaz es similar a SMTPClient.

El primer paso para utilizar MailKit sería instalarlo vía Nuget.
Install-Package MailKit

Enviar un email con MailKit es muy parecido a hacerlo con SMTPClient.
var mailMessage = new MimeMessage();

mailMessage.From.Add(new MailboxAddress("from name", "from email"));

mailMessage.To.Add(new MailboxAddress("to name", "to email"));

mailMessage.Subject = "subject";

mailMessage.Body = new TextPart("plain")

{

    Text = "Hello"

};

using (var smtpClient = new SmtpClient())

{

    smtpClient.Connect("smtp.gmail.com", 587, true);

    smtpClient.Authenticate("user", "password");

    smtpClient.Send(mailMessage);

    smtpClient.Disconnect(true);

}

Como ya mencioné, Mailkit soporta varios protocolos, más que SMTPClient, si buscas algo más que enviar un mensaje de correo electrónico, MailKit es una buena opción. Si no, quedate con el viejo y confiable SMTPClient.

Usar proveedores de envío de correo


La alternativa a SMTPClient/MailKit es utilizar un servicio especializado en envío de emails:

  • AWS SES (Simple Email Service), que puede ser un servidor SMTP.

  • Mandrill.NET (de MailChimp), tiene más características que SES: plantillas, códigos embebidos.

  • SendGrid, que puede ser un servidor o un cliente SMTP.


 

Publicar un comentario

3 Comentarios

  1. Tengo una aplicación Web creada con VS2010 que usa para el envío de correo el SMTPClient y dejó de funcionar, precisamente porque Microsoft está obligando a usar protocolos más seguros para los envíos de correo (desde la cuenta institucional).
    Lo raro del caso es que cuando la cuenta de correo origen no es institucional, el correo electrónico si se envía)
    El error que me está mostrando es:
    System.IO.IOException: No se puede escribir datos de en la conexión de transporte: net_io_connectionclosed. He revisado documentación sobre este error pero nada de lo que sugieren ha servido para superar el impase.
    Migrar toda la solución a una versión superior a VS 2017 para poder usar Mailkit no es algo viable en el corto plazo. Hay alguna otra forma de enviar correos electrónicos (que no se use SMTPClient) que sea compatible con VS 2010 ?

    ResponderBorrar