Skip to content

Instantly share code, notes, and snippets.

@antonio-leonardo
Created July 18, 2020 19:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save antonio-leonardo/347bf018ed7a049df1f5c733e27121a1 to your computer and use it in GitHub Desktop.
Save antonio-leonardo/347bf018ed7a049df1f5c733e27121a1 to your computer and use it in GitHub Desktop.
Class with complete and stable structures for sending e-mail
/// <summary>
/// Classe com estruturas completas e estáveis para envio de E-mail
/// </summary>
public class MailSender
{
/// <summary>
/// Login do SMTP
/// </summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly string _smptLogin;
/// <summary>
/// Senha de acesso ao SMTP
/// </summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly string _smptPassword;
/// <summary>
/// Servidor SMTP
/// </summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly string _smtpServer;
/// <summary>
/// Confirmação de E-Mail enviado ou não
/// </summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private static bool MailSent { get; set; }
/// <summary>
/// Objeto para emissão de E-Mail
/// </summary>
/// <param name="smtpServer">Servidor SMTP</param>
/// <param name="smptLogin">Emissor do E-Mail</param>
/// <param name="smptPassword">Senha do Emissor</param>
public MailSender(string smtpServer, string smptLogin, string smptPassword = null)
{
this._smptLogin = smptLogin;
this._smptPassword = smptPassword;
this._smtpServer = smtpServer;
}
/// <summary>
/// CallBack de envio de E-Mail
/// </summary>
/// <param name="sender">Objeto Emissor</param>
/// <param name="e">Argumento para o CallBack</param>
protected static void SendCompletedCallback(object sender, AsyncCompletedEventArgs e)
{
// Get the unique identifier for this asynchronous operation.
String token = (string)e.UserState;
if (e.Cancelled)
{
throw new Exception("Emissão de E-Mail cancelada ou interrompida.");
}
if (e.Error != null)
{
throw new Exception("Surgiram erros na emissão de E-Mail.", e.Error.InnerException);
}
else
{
MailSent = true;
}
}
/// <summary>
/// Responsável pelo envio de e-mail, através dos recursos nativos do .NET Framework
/// </summary>
/// <param name="sender">Usuário com credencial para acesso ao envio de e-mail</param>
/// <param name="replyTo">Responder para</param>
/// <param name="recipient">Destinatário da Mensagem</param>
/// <param name="subject">Assunto do E-Mail</param>
/// <param name="message">Corpo da mensagem de E-Mail</param>
/// <param name="port">Porta definida para envio de E-Mail</param>
/// <param name="ssl">Se haverá segurança SSL (TLS)</param>
/// <param name="encoding">Definição do padrão de caracteres para escrita do Texto</param>
public void SendMail(string sender, string replyTo, string recipient, string subject, string message, int port, bool ssl, Encoding encoding)
{
if (recipient.IsValidEmailString())
{
SmtpClient client = null;
System.Net.NetworkCredential credentials = null;
MailMessage mail = null;
try
{
this.MountMail(ref mail, sender, replyTo, recipient, subject, message, encoding);
if (_smptPassword != null)
{
credentials = new System.Net.NetworkCredential(_smptLogin, _smptPassword);
}
this.MountSMTP(ref client, port, ssl, SmtpDeliveryMethod.Network, credentials);
client.Send(mail);
if (!MailSent)
{
client.SendAsyncCancel();
}
}
catch (Exception ex)
{
throw new Exception("Erro duranto o envio de E-Mail", ex);
}
finally
{
if (client != null)
{
client.Dispose();
}
if (mail != null)
{
mail.Dispose();
}
}
}
}
/// <summary>
/// Responsável pelo envio de e-mail, através dos recursos nativos do .NET Framework
/// </summary>
/// <param name="sender">Usuário com credencial para acesso ao envio de e-mail</param>
/// <param name="replyTo">Responder para</param>
/// <param name="recipient">Destinatário da Mensagem</param>
/// <param name="subject">Assunto do E-Mail</param>
/// <param name="message">Corpo da mensagem de E-Mail</param>
/// <param name="port">Porta definida para envio de E-Mail</param>
/// <param name="ssl">Se haverá segurança SSL (TLS)</param>
/// <param name="encoding">Código de Texto</param>
public void SendMail(string sender, string replyTo, string recipient, string subject, string message, int port, bool ssl, int? encoding = null)
{
if (recipient.IsValidEmailString())
{
SmtpClient client = null;
System.Net.NetworkCredential credentials = null;
MailMessage mail = null;
try
{
this.MountMail(ref mail, sender, replyTo, recipient, subject, message, encoding);
if (_smptPassword != null)
{
credentials = new System.Net.NetworkCredential(_smptLogin, _smptPassword);
}
this.MountSMTP(ref client, port, ssl, SmtpDeliveryMethod.Network, credentials);
client.Send(mail);
if (!MailSent)
{
client.SendAsyncCancel();
}
}
catch (Exception ex)
{
throw new Exception("Erro duranto o envio de E-Mail", ex);
}
finally
{
if (client != null)
{
client.Dispose();
}
if (mail != null)
{
mail.Dispose();
}
}
}
}
/// <summary>
/// Montagem da mensagem de e-mail
/// </summary>
/// <param name="mail"></param>
/// <param name="sender"></param>
/// <param name="replyTo"></param>
/// <param name="recipient"></param>
/// <param name="subject"></param>
/// <param name="message"></param>
/// <param name="encoding"></param>
protected void MountMail(ref MailMessage mail, string sender, string replyTo, string recipient, string subject, string message, int? encoding = null)
{
mail = new MailMessage(sender.Trim(), recipient.Trim());
mail.ReplyToList.Add(replyTo);
mail.Subject = subject;
mail.Body = message;
if (encoding != null) { mail.BodyEncoding = Encoding.GetEncoding((int)encoding); }
}
/// <summary>
/// Montagem da mensagem de e-mail
/// </summary>
/// <param name="mail"></param>
/// <param name="sender"></param>
/// <param name="replyTo"></param>
/// <param name="recipient"></param>
/// <param name="subject"></param>
/// <param name="message"></param>
/// <param name="encoding"></param>
protected void MountMail(ref MailMessage mail, string sender, string replyTo, string recipient, string subject, string message, Encoding encoding)
{
mail = new MailMessage(sender.Trim(), recipient.Trim());
mail.ReplyToList.Add(replyTo);
mail.Subject = subject;
mail.Body = message;
mail.BodyEncoding = encoding;
}
/// <summary>
/// Montagem das configurações de SMTP
/// </summary>
/// <param name="client"></param>
/// <param name="port"></param>
/// <param name="ssl"></param>
/// <param name="method"></param>
/// <param name="credentials"></param>
protected void MountSMTP(ref SmtpClient client, int port, bool ssl, SmtpDeliveryMethod method, System.Net.NetworkCredential credentials = null)
{
client = new SmtpClient(_smtpServer);
client.Port = port;
client.DeliveryMethod = method;
client.UseDefaultCredentials = false;
client.EnableSsl = ssl;
if (credentials != null)
{
client.Credentials = credentials;
}
if (ssl)
{
//Add this line to bypass the certificate validation
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate (object s,
System.Security.Cryptography.X509Certificates.X509Certificate certificate,
System.Security.Cryptography.X509Certificates.X509Chain chain,
System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
return true;
};
}
client.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback);
}
}
/// <summary>
/// Classe responsável para Validação de E-Mail
/// </summary>
public static class EmailValidator
{
/// <summary>
/// Booleano de retorno se é um e-mail válido
/// </summary>
private static bool invalid { get; set; }
/// <summary>
/// Validação de String de E-Mail baseado em instruções pré-compiladas (ReGex)
/// </summary>
/// <param name="email">String com E-Mail a ser validado</param>
/// <returns>System.Boolean</returns>
public static bool IsValidEmailString(this string email)
{
invalid = false;
if (string.IsNullOrEmpty(email))
return false;
try
{
email = Regex.Replace(
email, @"(@)(.+)$", DomainMapper,
RegexOptions.None, TimeSpan.FromMilliseconds(200));
}
catch (RegexMatchTimeoutException)
{
return false;
}
if (invalid)
return false;
try
{
return Regex.IsMatch(email,
@"^(?("")("".+?(?<!\\)""@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))" +
@"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$",
RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250));
}
catch (RegexMatchTimeoutException)
{
return false;
}
}
/// <summary>
/// Auxiliar para mapeamento de Domínio na validação de string de E-Mail
/// </summary>
/// <param name="match">Validador</param>
/// <returns>System.String</returns>
private static string DomainMapper(Match match)
{
System.Globalization.IdnMapping idn = new System.Globalization.IdnMapping();
string domainName = match.Groups[2].Value;
try
{
domainName = idn.GetAscii(domainName);
}
catch (ArgumentException)
{
invalid = true;
}
return match.Groups[1].Value + domainName;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment