C# - Enviando Emails


Vamos enviar emails usando a linguagem C# ?

Então vamos que vamos...

Do que precisamos mesmo para enviar emails ???

Pegue uma mensagem, defina os endereços, defina o conteúdo e pronto basta enviar o email...

Você pode até não acreditar mas o código abaixo é tudo que precisamos para enviar um email:

//cria uma mensagem
MailMessage mail = new MailMessage();

//define os endereços
mail.From = new MailAddress("macoratti@yahoo.com");
mail.To.Add("macoratti@ig.com.br");

//define o conteúdo
mail.Subject = "Este é um simples ,muito simples email";
mail.Body = "Este é o corpo do email";

//envia a mensagem
SmtpClient smtp = new SmtpClient("smtp.gmail.com");
smtp.Send(mail);
'cria uma mensagem
Dim mail As New MailMessage()

'define os endereçcos
mail.From = New MailAddress("macoratti@yahoo.com")
mail.To.Add("macoratti@ig.com.br")

'define o conteúdo
mail.Subject = "Este é um email simples"
mail.Body = "Este é o corpo do email"

'envia a mensagem
Dim smtp As New SmtpClient("127.0.0.1")
smtp.Send(mail)
C# VB .NET

Observando o código acima podemos inferir que:

Precisamos da classe SmtpClient que é a classe usada para enviar o email para um servidor SMTP.

Além desta classe vamos precisar também das seguintes classes que são usadas para criar a mensagem de email que será enviada:

MailMessage - Classe que representa uma mensagem de email que pode ser enviada;

As instâncias da classe MailMessage são usadas para construir mensagens de email que são transmitidas para um servidor SMTP ; Esta classe expõe os seguintes membros:

Nome Descrição
MailMessage() Inicia uma instância vazia da classe
MailMessage(MailAddress, MailAddress) Inicia uma nova instância da classe usando os objetos da classe MailAddress.
MailMessage(String, String) Inicia uma nova instância da classe usando os objetos da classe String.
MailMessage(String, String, String, String) Inicia uma nova instância da classe MailMessage

A mensagem é composta do assunto : Subject e do Texto do assunto : Body.

MailAddress - Representa um endereço de email do remetente e/ou destinatário; Um endereço de Email é composto pelo nome de Usuário, nome do Host e, opcionalmente, um nome de exibição.

Attachment - Representa um anexo em um email. O conteúdo do anexo pode ser um String, Stream, ou nome de arquivo.

Para incluir o anexo no email usamos a propriedade Attachements da classe MailMessage.

Para clientes que não podem exibir o anexo no seu formato original, você pode especificar exibições alternativas, utilizando a propriedade AlternateViews da classe MailMessage.

E como fazemos para enviar uma mensagem de email usando o SmtpClient ?

Fazemos assim:

  1. Informamos o nome do servidor host SMTP que usaremos para enviar o email;
  • A propriedade Host define nome do host pode ser o nome ou o endereço IP;
  • A propriedade Port define a porta usada do servidor;

Podemos definir estas propriedades no arquivo de configuração da aplicação conforme o exemplo abaixo:
Exemplo de configuração no arquivo App.Config.

<configuration>
  <system.net>
    <mailSettings>
      <smtp deliveryMethod="network">
        <network
          host="localhost"
          port="25"
          defaultCredentials="true"
        />
      </smtp>
    </mailSettings>
  </system.net>
</configuration>
  1. Definimos as credenciais para a autenticação quando exigidas pelo servidor SMTP;
  • A propriedade Credentials define as credenciais usadas para autenticar o cliente que vai enviar o email;
  1. Informamos o endereço de email do remetente;
  2. Informamos o endereço de email ou a lista de endereço de email dos destinatários;
  3. Montamos a mensagem definindo o Subject e o Body;
  4. Enviamos a mensagem usando método Send ou SendAsync;

OBS: Se você estiver usando a aplicação no seu servidor então não há necessidade de nenhuma configuração. Se estiver usando localmente terá que configurar o servidor SMTP .

Para enviar efetivamente a mensagem podemos usar o método Send:

Send - Este método envia uma mensagem de email para um servidor SMTP. Este método não bloqueia a thread de chamada e permite que o chamador passe um objeto para o método que é invocado quando a operação for concluída;

Para receber uma notificação quando o email foi enviado ou a operação foi cancelada podemos adicionar um manipulador de eventos para o método SendCompleted;

Antes de chamar esse método, o nome do Host e a Porta devem ser definidas por meio de arquivos de configuração, definindo as propriedades relevantes ou passando essas informação para o construtor SMTP.

Lembrando que para enviar emails precisamos referenciar os seguintes namespaces no projeto:

Outro detalhe importante é a informação sobre o servidor SMTP como nome do Host, porta e credenciais do usuário.

Estas informações podem ser colocadas no arquivo de configuração da aplicação que no nosso caso é o arquivo App.Config.

Veja a seguir um exemplo de configuração usada com essas informações:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.net>
    <mailSettings>
      <smtp deliveryMethod="Network">
        <network host="seuservidorSMTP" port="25" defaultCredentials="true"  userName="macoratti" password="numsey"/>
      </smtp>
    </mailSettings>
  </system.net>
</configuration>

Para obter os valores do arquivo de configuração você pode usar o seguinte código:

                //obtem os valores smtp do arquivo de configuração . Não vou usar estes valores estou apenas mostrando como obtê-los

                Configuration configurationFile = WebConfigurationManager.OpenWebConfiguration(null);

                MailSettingsSectionGroup mailSettings = configurationFile.GetSectionGroup("system.net/mailSettings") as MailSettingsSectionGroup;

                if (mailSettings != null)

                {

                     string host = mailSettings.Smtp.Network.Host;

                     string password = mailSettings.Smtp.Network.Password;

                     string username = mailSettings.Smtp.Network.UserName;

                     int port = mailSettings.Smtp.Network.Port;

                }

O código acima requer a utilização dos seguintes namespaces:  using System.Configuration ,  using System.Web.Configuration e  using System.Web;

Obs: Para tornar mais segura estas informações podemos criptografar o arquivo de configuração mas isso eu vou falar em outro artigo.

Agora vamos da teoria para a prática onde abordarei de forma prática a incrível tarefa mais realizada hoje em dia que é enviar emails...

Abra o Visual C# 2010 Express Edition e crie um novo projeto do tipo Windows Application com o nome EmailHandler;

Em seguida clique com o botão direito do mouse sobre o nome do projeto Windows Forms Applications e selecione a opção Rename e altere o nome para EmailTeste;

Dessa forma teremos a solução chamada EmailHandler e um projeto Windows Forms chamado EmailTeste;

No formulário principal gerado no projeto EmailTeste, form1.cs, vamos incluir os seguintes controles:

O leiaute do formulário contendo estes controles deverá ficar parecido com a figura abaixo:

Vamos agora incluir na solução um novo projeto chamado EnviaEmail clicando sobre a solução e selecionando a opção Add -> New Project;

Na janela Add New Project selecione o template Class Library e informe o nome EnviaEmail e clique OK;

Altere o nome da classe Class1.cs para EnviarEmail.cs;

Vamos agora definir no arquivo EnviarEmail.cs a nossa classe que será responsável por enviar emails.

Esta classe terá 3 métodos:

Abra o arquivo e defina no início do mesmo os seguintes namespaces:

using System;
using System.Collections;
using System.Net.Mail;
using System.Net.Mime;
using System.Net;
using System.Text.RegularExpressions;
using System.Net.Configuration;

Em seguida defina o namespace da classe como:

namespace Macoratti.EnviaEmail

Vamos iniciar definindo o método EnviarMensagemEmail() mas antes de iniciar com o código da mesma vamos documentar o nosso método teclando 3 barras (/) de forma que o Visual C# abra o bloco <summary> para documentação do método e em seguida vamos declarar quais os parâmetros usados no método e qual o seu retorno:

/// <summary>
/// Transmite uma mensagem de email sem anexos
/// </summary>
/// <param name="Destinatario">Destinatario (Recipient)</param>
/// <param name="Remetente">Remetente (Sender)</param>
/// <param name="Assunto">Assunto da mensagem (Subject)</param>
/// <param name="enviaMensagem">Corpo da mensagem(Body)</param>
/// <returns>Status da mensagem</returns>

Dessa forma temos uma descrição do que o método faz , seus parâmetros e seu retorno. É uma boa prática sempre documentar o seu código.

     public static string EnviaMensagemEmail(string Destinatario, string Remetente,string Assunto, string enviaMensagem)
      {
            try
            {
                // valida o email
                bool bValidaEmail = ValidaEnderecoEmail(Destinatario);

                // Se o email não é validao retorna uma mensagem
                if (bValidaEmail == false)
                    return "Email do destinatário inválido: " + Destinatario;

                // cria uma mensagem
                MailMessage mensagemEmail = new MailMessage(Remetente,Destinatario,Assunto,enviaMensagem);

                SmtpClient client = new SmtpClient("smtp.gmail.com", 587);
                client.EnableSsl = true;
                NetworkCredential cred = new NetworkCredential("SEU_EMAIL@gmail.com", "SUA_SENHA");
                client.Credentials = cred;

                // inclui as credenciais
                client.UseDefaultCredentials = true;

                // envia a mensagem
                client.Send(mensagemEmail);

                return "Mensagem enviada para  " + Destinatario + " às " + DateTime.Now.ToString() + ".";
            }
            catch (Exception ex)
            {
                string erro = ex.InnerException.ToString();
                return ex.Message.ToString() + erro ;
            }
        }

O código da classe  EnviarMensagemComAnexos() a é dado a seguir. Ele faz a mesma coisa que o método anterior  obtendo os anexos e os incluindo na mensagem para envio;

    public static string EnviaMensagemComAnexos(string Destinatario, string Remetente,
                                string Assunto, string enviaMensagem, ArrayList anexos)
     {
            try
            {
                // valida o email
                bool bValidaEmail = ValidaEnderecoEmail(Destinatario);

                if (bValidaEmail == false)
                    return "Email do destinatário inválido:" + Destinatario;

                // Cria uma mensagem
                MailMessage mensagemEmail = new MailMessage(
                   Remetente, Destinatario,Assunto,enviaMensagem);
                // Obtem os anexos contidos em um arquivo arraylist e inclui na mensagem
                foreach (string anexo in anexos)
                {
                    Attachment anexado = new Attachment(anexo, MediaTypeNames.Application.Octet);
                    mensagemEmail.Attachments.Add(anexado);
                }

                SmtpClient client = new SmtpClient("smtp.gmail.com", 587);
                client.EnableSsl = true;
                NetworkCredential cred = new NetworkCredential("SEU_EMAIL@gmail.com", "SUA_SENHA");
                client.Credentials = cred;

                // Inclui as credenciais
                client.UseDefaultCredentials = true;

                // envia a mensagem
                client.Send(mensagemEmail);

                return "Mensagem enviada para " + Destinatario + " às " + DateTime.Now.ToString() + ".";
            }
            catch (Exception ex)
            {
                string erro = ex.InnerException.ToString();
                return ex.Message.ToString() + erro;
            }
        }

O método para validar emails é dado abaixo. Ela usa uma expressão regular para validar o email informado;

        /// <summary>
        /// Confirma a validade de um email
        /// </summary>
        /// <param name="enderecoEmail">Email a ser validado</param>
        /// <returns>Retorna True se o email for valido</returns>
        public static bool ValidaEnderecoEmail(string enderecoEmail)
        {
            try
            {
                //define a expressão regulara para validar o email
                string texto_Validar = enderecoEmail;
                Regex expressaoRegex = new Regex(@"\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,3}");

                // testa o email com a expressão
                if (expressaoRegex.IsMatch(texto_Validar))
                {
                    // o email é valido
                    return true;
                }
                else
                {
                    // o email é inválido
                    return false;
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

Agora só nos resta definir o código usado no formulário frmTesteEmail.cs que irá ser usado nos eventos dos botões de comando : Incluir, Cancelar e Enviar;

Antes temos que definir os seguintes namespaces no formulário:

using System;
using
System.Collections;
using
System.Windows.Forms;

A seguir vamos definir uma variável ArrayList para armazenar os anexos:

/// <summary>
///
Um array lista contento todos os anexos
/// </summary>
ArrayList aAnexosEmail;

Agora vemos o código associado ao evento Click dos botões de comando:

- Código do botão de comando Enviar:

        /// <summary>
        /// Envia uma mensagem de mail com ou sem anexos
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnEnviar_Click(object sender, EventArgs e)
        {
            if (String.IsNullOrEmpty(txtEnviarPara.Text))
            {
                MessageBox.Show("Endereço de email do destinatário inválido.", "Erro ");
                return;
            }
            if (String.IsNullOrEmpty(txtEnviadoPor.Text))
            {
                MessageBox.Show("Endereço de email do remetente inválido.", "Erro ");
                return;
            }
            if (String.IsNullOrEmpty(txtAssuntoTitulo.Text))
            {
                MessageBox.Show("Definição do assunto inválida.", "Erro ");
                return;
            }
            if (String.IsNullOrEmpty(txtMensagem.Text))
            {
                MessageBox.Show("Mensagem inválida.", "Erro ");
                return;
            }

            //separa os anexos em um array de string
            string[] arr = txtAnexos.Text.Split(';');
            //cria um novo arraylist
            aAnexosEmail = new ArrayList();
            //percorre o array de string e inclui os anexos
            for (int i = 0; i < arr.Length; i++)
            {
                if (!String.IsNullOrEmpty(arr[i].ToString().Trim()))
                {
                    aAnexosEmail.Add(arr[i].ToString().Trim());
                }
            }
            // Se existirem anexos , envia a mensagem com 
            // a chamada a EnviaMensagemComAnexos senão
            // usa o método enviaMensagemEmail
            if (aAnexosEmail.Count > 0)
            {
                string resultado = EnviaEmail.EnviaEmail.EnviaMensagemComAnexos(txtEnviarPara.Text,
                    txtEnviadoPor.Text, txtAssuntoTitulo.Text, txtMensagem.Text,
                    aAnexosEmail);
                MessageBox.Show(resultado, "Email enviado com sucesso");
            }
            else
            {
                string resultado = EnviaEmail.EnviaEmail.EnviaMensagemEmail(txtEnviarPara.Text,
                    txtEnviadoPor.Text, txtAssuntoTitulo.Text, txtMensagem.Text);

                MessageBox.Show(resultado, "Email enviado com sucesso");
            }
        }

O código valida o email e verifica se existem anexos chamando a rotina pertinente conforme o caso.

- Código do botão de comando Incluir:

       /// <summary>
        /// Incluir arquivos a serem anexaso na mensagem
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnIncluir_Click(object sender, EventArgs e)
        {
            if (ofd1.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    string[] arr = ofd1.FileNames;
                    aAnexosEmail = new ArrayList();
                    txtAnexos.Text = string.Empty;
                    aAnexosEmail.AddRange(arr);
                    foreach (string s in aAnexosEmail)
                    {
                        txtAnexos.Text += s + "; ";
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Error");
                }
            }

 

- Código do botão de comando Cancelar:

/// <summary>

/// Sai da aplica‡Æo

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

private void btnCancelar_Click(object sender, EventArgs e)

{

     Application.Exit();

}

 

Com isso temos tudo pronto para testar o projeto para envio de emails.

Obs: Se você não configurar o servidor SMTP (se estiver testando localmente) corretamente vai obter a seguinte mensagem de erro:

Pegue o projeto completo aqui: EmailHandler.zip

Eu sei é apenas C# , mas eu gosto...

Referências:

José Carlos Macoratti