.NET

19 mai, 2016

ASP .NET – Enviando e-mails via SMTP a partir de um banco de dados

Publicidade

Neste artigo vou mostrar como criar uma pequena aplicação ASP .NET Web Forms que permite enviar e-mails coletados a partir de um banco de dados e via SMTP.

Vamos supor que você tenha uma relação de e-mails armazenado em um banco de dados e que precisa criar uma aplicação web para enviar esses e-mails.

O banco de dados pode ser qualquer um, mas vamos usar um banco de dados Microsoft Access chamado Clientes.accdb contendo a tabela e-mails com a seguinte estrutura:

webf_email16

A tabela possui somente um campo Código e um campo E-mail onde temos os e-mails que vamos usar.

Você deseja também poder selecionar os e-mails que deseja enviar.

Muito bem vamos partir desse cenário e criar uma aplicação ASP .NET Web Forms que faça exatamente isso que você deseja.

Recursos usados: Visual Studio 2013 Express for Web.

Criando o projeto no Visual Studio

Abra o Visual Studio 2013 Express for web e crie um novo projeto ASP .NET Web Forms usando o template Empty com o nome Envia_EmailVBNET.

webf_email11

webf_email12

A seguir, no menu PROJECT clique em Add New Item.

Selecione o template Web Form e informe o nome Default.aspx e clique em OK.

webf_email13

Agora vamos incluir no projeto uma referência ao BootStrap.

No menu TOOLS clique em Nuget Package Manager -> Manage Nuget Packages for Solution. Depois digite bootstrap e localize o pacote.

A seguir, clique no botão Install para instalar o pacote no projeto:

webf_email14

Vamos incluir um novo WebForm em nosso projeto que será usado como página de erros.

No menu PROJECT, clique em Add New Item. Selecione o template Web Form e informe o nome PaginaErro.aspx e clique em OK.

A seguir, defina o seguinte código nesta página Web form:

<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="PaginaErro.aspx.vb" 
Inherits="Envia_Email_VBNET.PaginaErro" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <link href="Content/bootstrap.css" rel="stylesheet" />
    <style type="text/css">
        .auto-style1 {
            font-family: "Arial Rounded MT";
        }
        .auto-style2 {
            color: #CC0000;
        }
        .auto-style3 {
            font-family: "Arial Rounded MT";
            color: #CC0000;
        }
    </style>
</head>
<body>
    <h3> Macoratti .net</h3>
    <hr />
    <div class="well">
    <form id="form1" runat="server">
       <h3 class="auto-style3">Ocorreu um erro durante o processamento.</h3>
       <h3 class="auto-style1"><span class="auto-style2">Contate o Suporte</span>.</h3>
        <br />
       <hr />
       <strong><a href="Default.aspx">Retornar</a></strong>
    </form>
   </div>
</body>
</html>

webf_email17

Na figura acima vemos o leiaute da nossa página de erro que será exibida quando algum erro ocorrer.

Agora vamos criar uma interface na página Default.aspx para apresentar um formulário onde iremos realizar as operações para enviar os e-mails.

Vamos usar os controles TextBox, Button, CheckBoxList para criar a interface, conforme mostra o leiaute abaixo:

webf_email15

O código referente a este leiaute visualizado na guia Source é o seguinte:

%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="Envia_Email_VBNET._Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Enviar Email</title>
    <link href="Content/bootstrap.min.css" rel="stylesheet" />
    <style type="text/css">
        #form1 {
            width: 652px;
            background-color: #97EAFF;
        }
        .auto-style1 {
            color: #0033CC;
        }
    </style>
</head>
<body>
    <h2 class="auto-style1">Macoratti .net - Enviando Emails </h2>
    <div class="well">
        <form id="form1" runat="server">
            Recipiente(s):<br />
            <asp:TextBox ID="txtRecipiente" runat="server" Height="50px" Width="525px" TextMode="MultiLine"></asp:TextBox>
            <br />
            <asp:Button ID="btnRecipienteDB" runat="server"
                onclick="btnRecipienteDB_Click" Text="Recipiente a partir do Banco de dados" />
            <br />
            <asp:CheckBoxList ID="chklstRecipientesDB" runat="server" Visible="False"></asp:CheckBoxList>
             <asp:Button ID="btnIncluirSelecionado" runat="server"
                        Text="Adicionar Seleção" onclick="btnIncluirSelecionado_Click" Visible="False" />
            <br /> 
            Assunto:<br />
            <asp:TextBox ID="txtAssunto" runat="server" Height="18px" Width="522px"></asp:TextBox>
            <br />
            <br />
            Corpo do Email:<br />
            <asp:TextBox ID="txtEmailBody" runat="server" Height="290px" Width="520px" TextMode="MultiLine"></asp:TextBox>
            <br />
            <asp:Button ID="btnEnviar" runat="server" onclick="btnEnviar_Click" Text="Envia Email" />
         </form>
   </div>
</body>
</html>

O código usado é bem simples.

  • Referenciamos o bootstrap e estamos usando a classe Well no formulário;
  • Definimos os controles com seus nomes e propriedades e eventos.

A seguir, vamos definir o code-behind nos eventos dos controles.

Quando o formulário for apresentado, o usuário deverá obter a lista de e-mails a partir do banco de dados clicando no botão – Recipiente a partir do banco de dados.

O código do evento Click deste botão é dado a seguir:

  Protected Sub btnRecipienteDB_Click(sender As Object, e As EventArgs) Handles btnRecipienteDB.Click
        Try
            Dim dsClientes As DataSet = GetDataSetCliente()
            chklstRecipientesDB.DataSource = dsClientes.Tables(0)
            chklstRecipientesDB.DataTextField = "Email"
            chklstRecipientesDB.DataValueField = "Email"
            chklstRecipientesDB.DataBind()
            chklstRecipientesDB.Visible = True
            btnIncluirSelecionado.Visible = True
        Catch ex As Exception
            Server.Transfer("PaginaErro.aspx", True)
        End Try
    End Sub

Neste código, estamos criando um DataSet – dsClientes – a partir da chamada do método GetDataSetCliente().

A seguir, estamos vinculando o campo E-mail da tabela E-mails ao controle CheckBoxList e tornando visível os CheckListBox e o botão para incluir a seleção dos e-mails.

O código do método GetDataSetCliente() é visto abaixo:

Private Function GetDataSetCliente() As System.Data.DataSet
        Try
            'retornar a string de conexao da chave ConnectionString no Web.Config descomente o código abaixo e comente o código usado
            'Dim connectionString as String = ConfigurationManager.ConnectionStrings("conexaoEmails").ConnectionString
            Dim connectionString As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Dados\Clientes.accdb;Persist Security Info=False;"
            'cria um novo OleDB connection
            Dim conn As New System.Data.OleDb.OleDbConnection(connectionString)
            'passa o comando Select e a informação da conexão para o construtor 
            Dim da As New System.Data.OleDb.OleDbDataAdapter("SELECT Email FROM Emails", conn)
            'Cria um novo datas com a tabela : CLIENTES
            Dim ds As New System.Data.DataSet("Clientes")
            'Preenche o dataset e tabela com os dados retornados
            da.Fill(ds, "Clientes")
            'retorna o novo dataset
            Return ds
        Catch ex As Exception
            Server.Transfer("PaginaErro.aspx", True)
        End Try
    End Function

Com isso, teremos os e-mails exibidos na página e agora o usuário poderá selecionar os e-mails e clicar no botão: Adicionar Seleção.

O código do evento Click deste botão é dado a seguir:

Protected Sub btnIncluirSelecionado_Click(sender As Object, e As EventArgs) Handles btnIncluirSelecionado.Click
        Try
            Dim strRecipienteEmails As New StringBuilder()
            For Each chk As ListItem In chklstRecipientesDB.Items
                If chk.Selected Then
                    strRecipienteEmails.Append(chk.Value)
                    strRecipienteEmails.Append(";")
                End If
            Next
            txtRecipiente.Text = strRecipienteEmails.ToString()
            chklstRecipientesDB.Visible = False
            btnIncluirSelecionado.Visible = False

        Catch ex As Exception
            Throw ex
        End Try
End Sub

Este código verifica os e-mails marcados e copia o e-mail correspondente para o TextBox exibindo os e-mails que serão enviados.

Finalmente basta clicar no botão Enviar E-mail que tem o seguinte código no seu evento Click:

Protected Sub btnEnviar_Click(sender As Object, e As EventArgs) Handles btnEnviar.Click
        Try
            ' se voce quiser enviar emails diretametne do banco de dados
            ' descomente o codigo abaixo e ajuste para enviar 
            '----------------------------------------------------------
            ''Dim dsClientes As DataSet = GetDataSetCliente()
            ''If dsClientes.Tables("Clientes").Rows.Count > 0 Then
            ''    For Each dr As DataRow In dsClientes.Tables("Clientes").Rows
            ''        EnviaEmail(dr("Email").ToString())
            ''    Next
            ''End If
            '---------------------------------------------------------------
            Dim separador As Char() = {";"c}
            For Each _email As String In txtRecipiente.Text.Split(separador)
                 EnviaEmail(_email)
            Next
        Catch ex As Exception
            Server.Transfer("PaginaErro.aspx", True)
        End Try
    End Sub

Este código obtém os e-mails da caixa de texto e percorre cada um deles chamando o método EnviaEmail() para enviar o e-mail.

O código do método EnviaEmail() é dado a seguir:

Private Sub EnviaEmail(EmailAddress As String)
        Try
            'Cria uma instância da classe MailMessage
            Dim mail As New MailMessage()
            'destino
            mail.[To].Add(EmailAddress)
            'origem
            mail.From = New MailAddress("macoratti@yahoo.com")
            'assunto
            mail.Subject = txtAssunto.Text
            'corpo do email (texto)
            mail.Body = txtEmailBody.Text
            'é html ?
            mail.IsBodyHtml = True
            'cria instãncia STMP
            Dim smtp As New SmtpClient()
            'define o servidor SMTP
            smtp.Host = "smtp.gmail.com"
            'Dados do seu servidor SMTP
            smtp.Credentials = New System.Net.NetworkCredential("SeuNomeUsuario@gmail.com", "SuaSenha_gmail")
            'Suas credenciais SMTP
            'habilita o envio via SSL
            smtp.EnableSsl = True
            'envia o email
            smtp.Send(mail)
        Catch ex As Exception
            Server.Transfer("PaginaErro.aspx", True)
        End Try
    End Sub

Aqui você deve informar os dados do seu servidor SMTP ou usar outra forma de enviar os emails. (Veja artigo para enviar email usando o SendGrid).

Executando o projeto, iremos obter o seguinte resultado:

webf_email18

Após selecionar os e-mails, basta clicar no botão Envia E-mail.

Esse exemplo não deve ser considerado para enviar grandes quantidades de e-mail, mesmo porque esse tipo de atividade pode ser considerada prática de SPAM e dependendo da política do seu servidor SMTP isso pode te trazer problemas.

Para melhorar o desempenho, você pode considerar usar o método Parallel.ForEach para executar a operação de envio de e-mail de forma assíncrona.

A seguir, um exemplo onde estamos enviando diretamente do banco de dados onde criamos um DataTable – dtClientes:

Parallel.ForEach(dtClientes.AsEnumerable(),Function(linha)
             Return EnviaEmail(linha("Email").ToString()
   End Function)

Pegue o projeto completo aqui: Envia_Email_VBNET.zip