.NET Core ASP .NET C# Enviando e-mails no ASP.NET Core

O .NET possui um módulo nativo para o envio de e-mails. Entretanto, veja como facilitar este processo utilizando a biblioteca Coravel.

Wladimilson M. Nascimento 11 de setembro de 2020

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

Conheça o autor desse artigo

  • Foto Autor Wladimilson M. Nascimento
    Wladimilson M. Nascimento

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

    Posts desse Autor

Artigos relacionados