using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Mail;
using System.Text;
namespace Neo.Afx.WinService.Messages
{
///
/// A class for sending batches of emails.
///
public class EmailSender : MessageSender
{
SmtpClient _sender;
public EmailSender()
: base(MessageTypeEnum.Email)
{
}
#region InitializeSender
protected override void InitializeSender(MessageDatabase database)
{
var mailSettings = database.GetMailSetting();
_sender = new SmtpClient
{
DeliveryMethod = SmtpDeliveryMethod.Network,
Host = mailSettings.Host,
Port = mailSettings.Port,
EnableSsl = mailSettings.EnableSSL,
UseDefaultCredentials = mailSettings.UseDefaultCredentials
};
if(!mailSettings.UseDefaultCredentials && !string.IsNullOrEmpty(mailSettings.UserName))
{
_sender.Credentials = new NetworkCredential(mailSettings.UserName, mailSettings.Password, mailSettings.Domain);
}
}
#endregion
#region FinalizeSender
protected override void FinalizeSender(MessageDatabase database)
{
if(_sender != null)
{
_sender.Dispose();
_sender = null;
}
}
#endregion
protected override bool ShouldRun(int count, out string error)
{
error = null;
return true;
}
#region SendMessage
protected override bool SendMessage(Message message, List attachments, char recipientSeparator, out string error)
{
error = null;
var successful = true;
try
{
var recipients = ParseRecipients(message.Recipients, recipientSeparator);
if(!String.IsNullOrEmpty(recipients))
{
var hasAttachments = attachments != null && attachments.Count > 0;
var mailMessage = new MailMessage();
#region Create mailMessage
mailMessage.To.Add(recipients);
var cc = ParseRecipients(message.CC, recipientSeparator);
if(!String.IsNullOrEmpty(cc))
{
mailMessage.CC.Add(cc);
}
var bcc = ParseRecipients(message.BCC, recipientSeparator);
if(!String.IsNullOrEmpty(bcc))
{
mailMessage.Bcc.Add(bcc);
}
var fromAddress = message.Sender;
if(!String.IsNullOrEmpty(fromAddress))
{
mailMessage.From = new MailAddress(fromAddress);
}
mailMessage.IsBodyHtml = message.IsHtml;
mailMessage.Subject = message.Subject;
mailMessage.Body = message.MessageText;
#endregion
List streams = null;
if(hasAttachments)
{
// Attachment streams need to be open whilst sending
// so store them in a list for disposal later.
streams = new List();
#region Add attachments
foreach(var attachment in attachments)
{
var stream = new MemoryStream(attachment.ContentBLOB);
streams.Add(stream);
mailMessage.Attachments.Add(new Attachment(stream, attachment.Name, attachment.MimeType));
}
#endregion
}
_sender.Send(mailMessage);
if(hasAttachments)
{
// Clean up memory streams
foreach(var stream in streams)
{
stream.Close();
stream.Dispose();
}
}
}
}
catch(Exception ex)
{
error = ex.Message;
if (ex.InnerException != null) {
error += " " + ex.InnerException.Message;
}
successful = false;
}
return successful;
}
#endregion
#region ParseRecipients
static string ParseRecipients(string dbRecipients, char targetSeparator)
{
if(!String.IsNullOrEmpty(dbRecipients))
{
string recipients;
if(TryParseRecipients(dbRecipients, targetSeparator, ',', out recipients))
{
return recipients;
}
if(TryParseRecipients(dbRecipients, targetSeparator, ';', out recipients))
{
return recipients;
}
}
return dbRecipients;
}
#endregion
#region TryParseRecipients
static bool TryParseRecipients(string dbRecipients, char targetSeparator, char separator, out string recipients)
{
var s = new StringBuilder();
var result = false;
if(dbRecipients.IndexOf(separator) > 0)
{
result = true;
var recipientArray = dbRecipients.Split(new[] { separator }, StringSplitOptions.RemoveEmptyEntries);
for(var i = 0; i < recipientArray.Length; i++)
{
if(i > 0)
{
s.Append(targetSeparator);
}
s.Append(recipientArray[i]);
}
}
recipients = s.ToString();
return result;
}
#endregion
}
}