Enviando e-mails no ASP.NET Core

Todo sistema precisa notificar os usuários de algumas ações, sejam notificações visuais na aplicação ou fora dela. Se tratando de notificações fora do sistema, a forma mais comum de realizar isso é através do envio de e-mails.

Para realizar este processo, o .NET possui o namespace System.Net.Mail. Mesmo as classes dele não sendo complexas, utilizá-las requer uma série de configurações, algo que pode ser facilitado com o uso da biblioteca Coravel.

Coravel

Coravel é uma biblioteca .NET Core open-source que permite a implementação de agendamento de tarefas, caching, mensageria e envio de e-mails de forma simples e com pouca configuração.

Ela tem por objetivo ser intuitiva e direta ao ponto, para que o desenvolvedor possa focar nos pontos mais importantes da aplicação. Mesmo a biblioteca fornecendo vários recursos, vamos focar apenas na parte de envio de e-mails, que nos permite:

  • Utilizar Razor templates;
  • Visualizar um preview;
  • Definir as configurações no appsetings.json;
  • Enviar os e-mails para um arquivo de log para testes;
  • Entre outras opções.

Criando a aplicação

Para exemplificar o uso da biblioteca, crie uma aplicação ASP.NET Core:

dotnet new mvc --auth Individual -n exemploenvioemail

E adicione nela o pacote Coravel.Mailer:

dotnet add package Coravel.Mailer

Agora poderemos definir o envio de e-mail.

Definindo o tipo do e-mail

O módulo de e-mail da Coravel utiliza “Mailables” para enviar um e-mail. “Mailable” são classes que herdam Coravel.Mailer.Mail.Mailable e representam o tipo de e-mail que será enviado, como: “Novo usuário”, “Pedido realizado”, etc.

Neste artigo veremos o envio de e-mail quando um usuário for registrado, assim, iremos definir a classe abaixo:

using Coravel.Mailer.Mail;
using Microsoft.AspNetCore.Identity;

namespace ExemploEnvioEmail.Mailables
{
    public class NewUserMailable: Mailable<NewUserMailableViewModel>
    {
        private NewUserMailableViewModel _newUser;

        public NewUserMailable(NewUserMailableViewModel newUser) => this._newUser = newUser;

        public override void Build()
        {
            this.To(this._newUser)
                .From(new MailRecipient("contato@treinaweb.com.br", "Treinaweb Cursos"))
                .View("~/Views/Mail/NewUser.cshtml", this._newUser);
        }
    }
}

Nela, note que o e-mail é definido no método Build, onde em:

this.To(this._newUser)

É informado o remetente. Ele pode ser indicado como uma string:

To("mail@remente.com.br")

Como um objeto MailRecipient:

To(new MailRecipient("mail@remente.com.br", "Remente")

Ou como um objeto qualquer:

this.To(this._newUser)

Neste caso, o objeto precisa possuir uma propriedade pública chamada Email. Caso também tenha uma propriedade chamada Name, ela será utilizada como rótulo do e-mail. O nosso módulo possui essas propriedades:

public class NewUserMailableViewModel
{
    public string Name { get; set; }
    public string Email { get; set; }
    public string CallbackUrl { get; set; }
}

Este mesmo padrão pode ser aplicado com o From:

.From(new MailRecipient("contato@treinaweb.com.br", "Treinaweb Cursos"))

Por fim, é informado o template do e-mail:

.View("~/Views/Mail/NewUser.cshtml", this._user);

Também é possível definir HTML puro utilizando o método Html:

public override void Build()
{
    this.To(this._user)
        .From(new MailRecipient("contato@treinaweb.com.br", "Treinaweb Cursos"))
        .Html("HTML");
}

Para que isso seja feito, Mailable precisa definir o tipo string ( Mailable<string>), se não será gerado um erro.

Não é utilizado neste exemplo, mas também há os métodos:

  • Cc (cópia);
  • Bcc (cópia oculta);
  • ReplyTo (remente de resposta).

Que aceitam uma coleção de string ou MailRecipient.

Também é importante frisar que o nome da “Mailable” será utilizado para definir o assunto do e-mail. Como os controllers do ASP.NET Core. A biblioteca remove "Mailable" do nome e define o assunto com base nas demais palavras capitalizadas. Por exemplo, para a nossa classe (NewUserMailable), o assunto do e-mail será “New User”. Entretanto é possível mudar este comportamento informando o assunto do e-mail no método Subject:

this.To(this._newUser)
    .From(new MailRecipient("contato@treinaweb.com.br", "Treinaweb Cursos"))
    .Subject($"Bem vindo {this._newUser.Name}")
    .View("~/Views/Mail/NewUser.cshtml", this._newUser);

Mas para este artigo, iremos seguir o padrão da biblioteca.

Criando o template do e-mail

Como vimos no tópico acima, o template do e-mail pode ser um arquivo Razor, definido no método View. Este arquivo segue o mesmo padrão de uma View:

@model ExemploEnvioEmail.Models.NewUserMailableViewModel

@{
   Layout = null;
}

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
    <table border="0" cellpadding="0" cellspacing="0" width="100%">
        <tr>
        <td align="center">
            <table border="0" cellpadding="0" cellspacing="0" width="100%">
                <tr>
                    <td align="center" valign="top">
                      <h1>Bem vindo: @Model.Name</h1>
                    </td>
                </tr>
            </table>
        </td>
    </tr>
    <tr>
        <td align="center">
            <table border="0" cellpadding="0" cellspacing="0" width="100%" >
              <tr>
                <td>
                    <p>
                        Bem vindo @Model.Name!
                    </p>
                    <p>
                        Estamos felizes que agora você faz parte da nossa comunidade. Por favor, clique <a href="@Html.DisplayFor(m => m.CallbackUrl)">aqui</a> para confirmar seu e-mail. Ou copie e cole no navegador o link abaixo:
                    </p>
                    <p>
                        <a href="@Html.DisplayFor(m => m.CallbackUrl)">@Html.DisplayFor(m => m.CallbackUrl)}</a>
                    </p>
                </td>
              </tr>
            </table>
        </td>
    </tr>
    <tr>
        <td align="center">
            <table border="0" cellpadding="0" cellspacing="0" width="100%">
              <tr>
                <td align="left">
                  <p>    
                    <a href="https://www.treinaweb.com.br">Treinaweb</a> | <a href="https://www.treinaweb.com.br/blog">Treinaweb Blog</a>
                </td>
              </tr>
            </table>
        </td>
    </tr>
    </table>
</body>
</html>

Note que no início do arquivo, indicamos o model:

@model ExemploEnvioEmail.Models.NewUserMailableViewModel

E que não deve ser utilizado o layout padrão da aplicação:

@{
   Layout = null;
}

Por causa disso, no arquivo é definida uma página HTML completa. À frente veremos o uso de um layout.

Com o nosso “Mailable” e View/Template definidos, podemos configurar o módulo de e-mail da Coravel na nossa aplicação.

Configurando o Coravel.Mailer

Para configurar a Coravel.Mailer, é necessário adicionar o seu serviço no método ConfigureServices:

public void ConfigureServices(IServiceCollection services)
{
    //..Código omitido

    //Habilitando o Coravel.Mailer
    services.AddMailer(this.Configuration);
}

E no arquivo appsettings.json é necessário indicar qual será o Driver utilizado para enviar os e-mails. Pode ser indicado um servidor SMTP:

"Coravel": {
  "Mail": {
    "Driver": "SMTP",
    "Host": "smtp.mail.to",
    "Port": 2525,
    "Username": "usuario",
    "Password": "senha"
  }
}

Ou um arquivo de log:

"Coravel": {
  "Mail": {
    "Driver": "FileLog"
  }
}

Neste caso, os e-mails serão enviados para um arquivo chamado mail.log, criado na raiz do projeto. Este tipo de configuração é ideal durante o desenvolvimento e testes da aplicação. E será ele que utilizaremos neste artigo.

Por fim, só é necessário enviar o e-mail.

C# (C Sharp) - Introdução ao ASP.NET Core
Curso de C# (C Sharp) - Introdução ao ASP.NET Core
CONHEÇA O CURSO

Enviando e-mails com Coravel.Mailer

O serviço do módulo de e-mail da Coravel adiciona nas dependências da aplicação uma instância de Coravel.Mailer.Mail.IMailer, desta forma, podemos definir que ela será recebida no construtor do controller:

private readonly IMailer _mailer;

public AccountController(
    /* Código omitido */
    IMailer mailer)
{
    /* Código omitido */
    _mailer = mailer;

}

Com isso, em qualquer action dele, um e-mail pode ser enviado com o método SendAsync:

public async Task<IActionResult> Register(RegisterViewModel model, string returnUrl = null)
{
    /* Código omitido */
    await this._mailer.SendAsync(new NewUserMailable(
        new NewUserMailableViewModel {
            Name = user.UserName,
            Email = user.Email,
            CallbackUrl = callbackUrl
        }
    ));

    /* Código omitido */
}

Agora, sempre que um usuário for registrado na aplicação:

Cadastro de um usuário

O e-mail enviado será salvo no arquivo mail.log:

---------------------------------------------
Subject: New User
To: mail@teste.com.br <mail@teste.com.br>    
From: Treinaweb Cursos <contato@treinaweb.com.br>
ReplyTo: 
Cc: 
Bcc: 
---------------------------------------------



<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
    <table border="0" cellpadding="0" cellspacing="0" width="100%">
        <tr>
        <td align="center">
            <table border="0" cellpadding="0" cellspacing="0" width="100%">
                <tr>
                    <td align="center" valign="top">
                      <h1>Bem vindo: mail@teste.com.br</h1>
                    </td>
                </tr>
            </table>
        </td>
    </tr>
    <tr>
        <td align="center">
            <table border="0" cellpadding="0" cellspacing="0" width="100%" >
              <tr>
                <td>
                    <p>
                        Bem vindo mail@teste.com.br!
                    </p>
                    <p>
                        Estamos felizes que agora você faz parte da nossa comunidade. Por favor, clique <a href="https://localhost:5001/Account/ConfirmEmail?userId=3a3c71fd-eee3-44c5-b309-4cd55fb2a4df&code=CfDJ8BvCiBo0fQdGsoZDKA5HQm9WOefgiQKTgLo5rDFLbeUAOOFCIfiApXKu%2F6crEeW7wdrgz9h5Z0Y15NdZivlzQ4duSNFcOmbSObG0fdMbGTQ%2ByvC02wR1Av9QFxL%2Fkc5Vg0nwVtsrttBmAeFMHZSxnokR1n0rI9rUyzUpxAYywdpPJOhHW2r6DsSdK0VWp2u6Xe1uWsLDXmSMeMu96g8yZNz18N1SCPHgjNrU8eJdK1wP4Q5vUj%2Bdn21epFqNjaM5Fw%3D%3D">aqui</a> para confirmar seu e-mail. Ou copie e cole no navegador o link abaixo:
                    </p>
                    <p>
                        <a href="https://localhost:5001/Account/ConfirmEmail?userId=3a3c71fd-eee3-44c5-b309-4cd55fb2a4df&code=CfDJ8BvCiBo0fQdGsoZDKA5HQm9WOefgiQKTgLo5rDFLbeUAOOFCIfiApXKu%2F6crEeW7wdrgz9h5Z0Y15NdZivlzQ4duSNFcOmbSObG0fdMbGTQ%2ByvC02wR1Av9QFxL%2Fkc5Vg0nwVtsrttBmAeFMHZSxnokR1n0rI9rUyzUpxAYywdpPJOhHW2r6DsSdK0VWp2u6Xe1uWsLDXmSMeMu96g8yZNz18N1SCPHgjNrU8eJdK1wP4Q5vUj%2Bdn21epFqNjaM5Fw%3D%3D">https://localhost:5001/Account/ConfirmEmail?userId=3a3c71fd-eee3-44c5-b309-4cd55fb2a4df&code=CfDJ8BvCiBo0fQdGsoZDKA5HQm9WOefgiQKTgLo5rDFLbeUAOOFCIfiApXKu%2F6crEeW7wdrgz9h5Z0Y15NdZivlzQ4duSNFcOmbSObG0fdMbGTQ%2ByvC02wR1Av9QFxL%2Fkc5Vg0nwVtsrttBmAeFMHZSxnokR1n0rI9rUyzUpxAYywdpPJOhHW2r6DsSdK0VWp2u6Xe1uWsLDXmSMeMu96g8yZNz18N1SCPHgjNrU8eJdK1wP4Q5vUj%2Bdn21epFqNjaM5Fw%3D%3D</a>
                    </p>
                </td>
              </tr>
            </table>
        </td>
    </tr>
    <tr>
        <td align="center">
            <table border="0" cellpadding="0" cellspacing="0" width="100%">
              <tr>
                <td align="left">
                  <p>    
                    <a href="https://www.treinaweb.com.br">Treinaweb</a> | <a href="https://www.treinaweb.com.br/blog">Treinaweb Blog</a>
                </td>
              </tr>
            </table>
        </td>
    </tr>
    </table>
</body>
</html>

Coravel CLI

Outro recurso da Coravel que não citei é a sua ferramenta de linha de comando, o Coravel CLI. Esta ferramenta é uma global tool do .NET Core que pode ser instalada com o comando abaixo:

dotnet tool install --global coravel-cli

Entre os recursos que ela fornece, há a possibilidade de adicionar ao projeto o módulo de e-mail da biblioteca com o comando abaixo:

coravel mail install

Ele irá adicionar ao projeto a referência Coravel.Mailer e os arquivos:

  • ~/Views/Mail/_ViewStart.cshtml: Configuração que permite que as Views utilizem os templates da Coravel;
  • ~/Views/Mail/_ViewImports.cshtml: Configuração que permite o uso dos componentes definidos pela biblioteca;
  • ~/Views/Mail/Example.cshtml: Exemplo de uma View
  • ~/Mailables/Example.cs: Exemplo de um “Mailable”

Mesmo que a biblioteca Coravel.Mailer já esteja configurada na nossa aplicação, execute o comando acima. Ao fazer isso, poderemos alterar a nossa View para:

@model ExemploEnvioEmail.Models.NewUserMailableViewModel

@{
   ViewBag.Heading = "Bem vindo: " + Model.Name;
   ViewBag.Preview = "Obrigado por se registrar no nosso sistema";
}

<p>
    Bem vindo @Model.Name!
</p>
<p>
    Estamos felizes que agora você faz parte da nossa comunidade. Por favor, clique no botão abaixo para confirmar seu registro.
    @await Component.InvokeAsync("EmailLinkButton", new  { text = "Confirmar", url = Model.CallbackUrl })
</p>
<p>
    Ou copie e cole no navegador o link abaixo:
</p>
<p>
    <a href="@Html.DisplayFor(m => m.CallbackUrl)">@Html.DisplayFor(m => m.CallbackUrl)</a>
</p>
@section links
{
    <a href="https://www.treinaweb.com.br">Treinaweb</a> | <a href="https://www.treinaweb.com.br/blog">Treinaweb blog</a>
}

Como agora ela está utilizando o template da Coravel, foi possível definir algumas configurações:

  • ViewBag.Heading: Título do e-mail;
  • ViewBag.Preview: Preview do e-mail, para aplicações que fornecem isso;
  • section links: Links exibidos no rodapé do e-mail.

Não foi aplicado no exemplo acima, mas o template da biblioteca também possui a configuração ViewBag.Footer (ou section footer), para a definição do rodapé. Também é possível definir no arquivo de appsetting.json, os atributos:

"Coravel": {
    "Mail": {
        /* Logo da empresa  */
        "LogoSrc": "URL",

        /* Endereço, exibido no rodapé dos e-mails */
        "CompanyAddress": "RUA",

        /* Nome da empresa, exibido no rodaroé dos e-mails */
        "CompanyName": "Empresa",

        /* Cor utilizada no cabeçalho dos e-mails */
        "PrimaryColor": "#FFFFFF"
    }
}

Quando informados, esses atributos serão aplicados em todos os e-mails.

Conclusão

O módulo nativo de envio de e-mails do .NET é bem completo e eficiente, entretanto, a Coravel também fornece um módulo tão bom quanto, além de ser mais simples e cheio de recursos.

Devido a sua facilidade de configuração, sempre que necessitar enviar e-mails na sua aplicação, recomendo que verifique se esta biblioteca atende as suas necessidades. Pode ter certeza que a sua implementação será mais rápida que a implementação do módulo de e-mails do .NET.

Você pode ver o código completo da aplicação no meu GitHub.

Deixe seu comentário

Instrutor, nerd, cinéfilo e desenvolvedor nas horas vagas. Graduado em Ciências da Computação pela Universidade Metodista de São Paulo.

© 2004 - 2019 TreinaWeb Tecnologia LTDA - CNPJ: 06.156.637/0001-58 Av. Paulista, 1765, Conj 71 e 72 - Bela Vista - São Paulo - SP - 01311-200