ASP .NET Core 3.1 -  Enviando Emails


Neste artigo veremos como enviar emails em um projeto ASP .NET Core 3.1.

Hoje vamos recordar como enviar emails com a ASP .NET Core. Veremos como enviar emails texto, com anexos e com modelos HTML.

Os recursos usados são:

Criando o projeto no VS 2019 e definindo o Model

Abra o VS 2019 Community e crie um novo projeto via menu File-> New Project;

Selecione o template ASP .NET Core Web Application, e, Informe o nome da solução AspEmail (ou outro nome a seu gosto);

A seguir selecione .NET Core e ASP .NET Core 3.1 e marque o template API e as configurações conforme figura abaixo:

Crie uma pasta Models no projeto e nesta pasta crie a classe EmailRequest que representa um email:

public class EmailRequest
{
    public string ToEmail { get; set; }
    public string Subject { get; set; }
    public string Body { get; set; }
    public List<IFormFile> Attachments { get; set; }
}

Aqui estamos definindo 4 propriedades e estamos usando a interface IFormFile que é usada para enviar os anexos ou attachments. Esta interface representa um arquivo enviado com o HttpRequest.

Definindo as configurações do Mail

Precisamos definir alguns parãmetros confidenciais necessários para o envio de emails, como email-id e senha o nome do servidor SMTP, etc.(você precisa se autenticar para poder enviar um email).

Vamos armazenar essas informações no arquivo appsettings.json (embora isso não seja muito recomendável).

{
  "EmailSettings": {
    "Mail": "<seu_MAIL>",
    "DisplayName": "<seu_nome>",
    "Password": "<sua_senha>",
    "Host": "smtp.gmail.com",
    "Port": 587
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}
 
  • Mail - É o ID de email do qual você deseja enviar um email.
  • DisplayName - É o nome que aparece no destinatário.
  • Host - É o nome que identifica o seu servidor de Email
  • Port - É a porta usada
 

Eu estou usando o servidor SMTP do GMail e as informações relacionadas com minha conta.

Agora abra o arquivo appsettings.Development.json e inclua as mesmas configurações agora com os dados reais para poder enviar o email.

{
  "EmailSettings": {
    "Mail": "josecarlosmacoratti@gmail.com",
    "DisplayName": "Macoratti",
    "Password": "*************",
    "Host": "smtp.gmail.com",
    "Port": 587
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

Durante o desenvolvimento, é recomendável adicionar dados que devem ser mantidos em sigilo no appsettings.Development.Json. Este arquivo é gerado ao definir a variável de ambiente como desenvolvimento.

Ao adicionar o projeto no repositório, você pode excluir o appsettings.Development.json, para que o GIT ignore o arquivo e não o confirme no repositório principal. Dessa forma, podemos ter uma boa separação de informações confidenciais que serão usadas somente em desenvolvimento.

Obs: O mais seguro é usar os dados de uma conta de testes.

Os servidores SMTP ou Simple Mail Transfer Protocol são aplicativos cujo objetivo principal é enviar e receber e-mails. Quando você envia um email, o servidor SMTP determina o domínio de destino e retransmite o email para o servidor correspondente.

O servidor SMTP do Gmail permite enviar até 2.000 e-mails por dia o que é muito bom para começar, certo?

Então para usar o SMTP do Gmail você vai ter que ter uma conta e obter as seguintes informações:

- O seu Gmail ID (não use um ID de email pessoal, é muito arriscado)
- A sua senha.
- O Host ou endereço do servidor SMTP - Se você estiver usando o Gmail, use: smtp.gmail.com
- Porta - Se estiver usando o Gmail ,  use :  465 (SSL) ou 587 (TLS)

Agora só falta mais um detalhe. Você precisa permitir que sua conta do Gmail envie e-mails usando aplicativos externos.

Pra ativar isso, acesse https://myaccount.com/security e marque a opção para habilitar o Acesso a aplicativos menos seguro.

Configurando o serviço de Email

Após definir a configuração das informações para usar o servidor SMTP precisamos criar uma classe que vai tratar os detalhes destas informações.

Para isso crie uma classe EmailSettings na pasta Models:

public class EmailSettings
{
    public string Mail { get; set; }
    public string DisplayName { get; set; }
    public string Password { get; set; }
    public string Host { get; set; }
    public int Port { get; set; }
}

Agora podemos registrar o serviço na classe Startup :

        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<EmailSettings>(Configuration.GetSection("EmailSettings"));
            services.AddControllers();
        }

Neste código usamos uma instância de IConfiguration para o arquivo appsettings.json, e, como estamos no ambiente de desenvolvimento, por padrão, ele lerá os dados do appsettings.Development.Json.

Criando a camada de Serviço para enviar os Email

Vamos criar a seguir a nossa camada de serviço para enviar os emails.

Crie uma pasta Services no projeto e nesta pasta crie a interface IMailService:

using AspEmail.Models;
using System.Threading.Tasks;
namespace AspEmail.Services
{
    public interface IMailService
    {
        Task SendEmailAsync(EmailRequest emailRequest);
    }
}

A seguir crie a classe MailService que implementa esta interface :

using AspEmail.Models;
using Microsoft.Extensions.Options;
using System.IO;
using System.Net;
using System.Net.Mail;
using System.Threading.Tasks;
namespace AspEmail.Services
{
    public class MailService : IMailService
    {
        private readonly EmailSettings _mailSettings;
        public MailService(IOptions<EmailSettings> emailSettings)
        {
            _mailSettings = emailSettings.Value;
        }
        public async Task SendEmailAsync(EmailRequest mailRequest)
        {
            MailMessage message = new MailMessage();
            SmtpClient smtp = new SmtpClient();

            message.From = new MailAddress(_mailSettings.Mail, _mailSettings.DisplayName);
            message.To.Add(new MailAddress(mailRequest.ToEmail));
            message.Subject = mailRequest.Subject;

            if (mailRequest.Attachments != null)
            {
                foreach (var file in mailRequest.Attachments)
                {
                    if (file.Length > 0)
                    {
                        using (var ms = new MemoryStream())
                        {
                            file.CopyTo(ms);
                            var fileBytes = ms.ToArray();
                            Attachment att = new Attachment(new MemoryStream(fileBytes), file.FileName);
                            message.Attachments.Add(att);
                        }
                    }
                }
            }

            message.IsBodyHtml = false;
            message.Body = mailRequest.Body;
            smtp.Port = _mailSettings.Port;
            smtp.Host = _mailSettings.Host;
            smtp.EnableSsl = true;
            smtp.UseDefaultCredentials = false;
            smtp.Credentials = new NetworkCredential(_mailSettings.Mail, _mailSettings.Password);
            smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
            await smtp.SendMailAsync(message);
        }
    }
}

Vamos entender o código:

- Criamos um novo objeto MailMessage e para enviá-lo usando uma instância SMTPClient.
- Criamos um novo objeto SMTPClient
- A seguir estaremos preenchendo os dados relacionados à mensagem como assunto, corpo, etc.  do  mailRequest e os dados que obtemos do nosso arquivo JSON
- Adicionamos o endereço do remetente junto com o nome e o ID do correio do destinatário
- Se houver anexos no objeto do request, transformamos o arquivo em um anexo e o adicionamos à mensagem de email
- Podemos também enviar mensagens com tags HTML como corpo.
- Para enviar a mensagem usamos o método SendMailAsync da SMTP

Temos que registrar o nosso serviço de Email criado no arquivo Startup:

        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<EmailSettings>(Configuration.GetSection("EmailSettings"));

            services.AddTransient<IMailService, Services.MailService>();

            services.AddControllers();
        }

 

Criando o controlador EmailController

Agora precisamos criar o controlador EmailController na pasta Controllers que vai usar o serviço criado para enviar os emails.

using AspEmail.Models;
using AspEmail.Services;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Threading.Tasks;
namespace AspEmail.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class EmailController : Controller
    {
        private readonly IMailService mailService;
        public EmailController(IMailService mailService)
        {
            this.mailService = mailService;
        }
        [HttpPost("send")]
        public async Task<IActionResult> SendMail([FromForm] EmailRequest request)
        {
            try
            {
                await mailService.SendEmailAsync(request);
                return Ok();
            }
            catch (Exception)
            {
                throw;
            }
        }
        public IActionResult Index()
        {
            return View();
        }
    }
}

No controlador injetamos o serviço para enviar Emails no construtor e definimos o método Action HttpPost  SendMail() que obtem os dados do email e usa o método SendEmail do serviço

Agora, postemos fazer o teste enviando emails. Para isso podemos usar o Postman.

Para instalar o Postman acesse esse link : https://www.getpostman.com/apps ou abra o Google Chrome e digite postam e a seguir clique no link:  Postman - Chrome Web Store

Na janela que será aberta clique no botão - Usar no Chrome:

A seguir registre uma conta e faça o login.

Pronto ! Já podemos usar o Postman.

Executando o nosso projeto Web API vamos obter o endereço e a porta de atendimento.

Ai basta usar o endereço e montar o request POST com com um form-data no Postman:

Pegue o projeto aqui:  AspEmail.zip

"Mas, não vos alegreis porque se vos sujeitem os espíritos; alegrai-vos antes por estarem os vossos nomes escritos nos céus."
Lucas 10:20

Referências:


José Carlos Macoratti