C# EmailService

Date: 2016-12-16
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net.Mail;
using System.Threading.Tasks;
using System.Web;
using Common.Logging;
using Application.Business.UnitOfWork;
using Application.Business.Repository;
using System.Text;

namespace Application.Business.Service
{
    public class EmailService
    {
        static readonly string host;
        static readonly int port;

        private class SerializableAttachment
        {
            public string Name;
            public string Content;
            public string ContentType = "application/octet-stream";
        }

        private class SerializableMailMessage
        {
            public string Sender = "";
            public string From = "";
            public List To = new List();
            public List CC = new List();
            public List BCC = new List();
            public List ReplyTo = new List();
            public string Subject = "";
            public string Body = "";
            public int Priority = 0;
            public bool IsBodyHtml = true;
            public List<keyvaluepair<string, string>> Headers = new List<keyvaluepair<string, string>>();
            public List Attachments = new List();
        }

        static EmailService()
        {
            host = ConfigurationManager.AppSettings["SmtpHost"];
            port = Convert.ToInt32(ConfigurationManager.AppSettings["SmtpPort"]);

            //unitOfWorkFactory = new UnitOfWorkFactory();
            //repositoryFactory = new RepositoryFactory();
        }

        private static string GetMailAddressAsString(MailAddress mailAddress)
        {
            if (mailAddress != null)
            {
                return mailAddress.ToString();
            }
            return null;
        }

        private static IEnumerable GetAddressList(MailAddressCollection mailAddressCollection)
        {
            if (mailAddressCollection != null)
            {
                return mailAddressCollection.Select(e => GetMailAddressAsString(e)).Where(e => !String.IsNullOrWhiteSpace(e));
            }
            return new List();
        }

        private static MailAddress GetMailAddress(string mailAddress)
        {
            if (!String.IsNullOrWhiteSpace(mailAddress))
            {
                return new MailAddress(mailAddress);
            }
            return null;
        }

        private static void AddMailAddresses(MailAddressCollection collection, IEnumerable addresses)
        {
            foreach (var address in addresses)
            {
                if (!String.IsNullOrWhiteSpace(address))
                {
                    collection.Add(new MailAddress(address));
                }
            }
        }

        private static byte[] GetAllBytesFromStream(Stream stream)
        {
            stream.Position = 0;
            var bytes = default(byte[]);
            using (var memstream = new MemoryStream())
            {
                stream.CopyTo(memstream);
                bytes = memstream.ToArray();
                return bytes;
            }
        }

        public static string SerializeMailMessage(MailMessage mailMessage)
        {
            var s = new SerializableMailMessage();
            s.Sender = GetMailAddressAsString(mailMessage.Sender);
            s.From = GetMailAddressAsString(mailMessage.From);
            s.To.AddRange(GetAddressList(mailMessage.To));
            s.CC.AddRange(GetAddressList(mailMessage.CC));
            s.BCC.AddRange(GetAddressList(mailMessage.Bcc));
            s.ReplyTo.AddRange(GetAddressList(mailMessage.ReplyToList));
            s.Subject = mailMessage.Subject;
            s.Body = mailMessage.Body;
            s.IsBodyHtml = mailMessage.IsBodyHtml;
            s.Priority = (int)mailMessage.Priority;

            foreach (var key in mailMessage.Headers.AllKeys)
            {
                s.Headers.Add(new KeyValuePair<string, string> (key, mailMessage.Headers[key]));
            }

            s.Attachments.AddRange(mailMessage.Attachments.Select(a => {
                a.ContentStream.Position = 0;
                return new SerializableAttachment()
                {
                    Name = a.Name,
                    ContentType = a.ContentType.MediaType,
                    Content = Convert.ToBase64String(GetAllBytesFromStream(a.ContentStream))
                };
            }));

            return JsonConvert.SerializeObject(s);
        }

        public static MailMessage DeserializeMailMessage(string mailMessageJson)
        {
            var s = JsonConvert.DeserializeObject(mailMessageJson);

            MailMessage message = new MailMessage();
            message.Sender = GetMailAddress(s.Sender);
            message.From = GetMailAddress(s.From);
            AddMailAddresses(message.To, s.To);
            AddMailAddresses(message.CC, s.CC);
            AddMailAddresses(message.Bcc, s.BCC);
            AddMailAddresses(message.ReplyToList, s.ReplyTo);
            message.Subject = s.Subject;
            message.Body = s.Body;
            message.Priority = (MailPriority)s.Priority;
            message.IsBodyHtml = s.IsBodyHtml;

            foreach (var header in s.Headers)
            {
                message.Headers[header.Key] = header.Value;
            }

            foreach (var attachment in s.Attachments)
            {
                var stream = new MemoryStream(); // using or Dispose not needed here memory stream is managed            
                var data = Convert.FromBase64String(attachment.Content);
                stream.Write(data, 0, data.Length);
                stream.Position = 0;
                message.Attachments.Add(new Attachment(stream, attachment.Name, attachment.ContentType));
            }
            return message;
        }

        //        public static async Task AddEmailToQueue(string from, IEnumerable to, string subject, string body, bool ishtml = false)
        //        {
        //            var message = new MailMessage
        //            {
        //                Subject = subject,
        //                From = new MailAddress(@from),
        //                Body = body,
        //                IsBodyHtml = ishtml
        //            };

        //#if DEBUG
        //            to = new[] { ConfigurationManager.AppSettings["DebugEmailAddress"]};
        //#endif
        //            foreach (var address in to)
        //            {
        //                if (!String.IsNullOrEmpty(address))
        //                {
        //                    message.To.Add(address);
        //                }
        //            }
        //            await AddEmailToQueue(message);
        //        }

        //public static async Task AddEmailToQueue(MailMessage mailMessage) {
        //    var mailMessageJson = SerializeMailMessage(mailMessage);

        //    using (var unitOfWork = unitOfWorkFactory.Create())
        //    {
        //        var repository = repositoryFactory.Create(unitOfWork);
        //        var emailQueueRepository = repositoryFactory.Create(unitOfWork);

        //        var emailQueueItem = new EmailQueueItem();
        //        emailQueueItem.Id = Guid.NewGuid();
        //        emailQueueItem.InsertedAt = DateTime.Now;
        //        emailQueueItem.LastException = String.Empty;
        //        emailQueueItem.LastProcessedAt = null;
        //        emailQueueItem.EmailFrom = GetMailAddressAsString(mailMessage.From);
        //        emailQueueItem.EmailTo = String.Join(";", mailMessage.To.Select(e => e.ToString()));
        //        emailQueueItem.EmailSubject = mailMessage.Subject;
        //        emailQueueItem.EmailContent = mailMessageJson;

        //        emailQueueRepository.Add(emailQueueItem);

        //        await unitOfWork.ValidateAndCommitAsync();
        //    }

        //    try
        //    {
        //        ScheduledTaskService.TriggerTaskNow();
        //    }
        //    catch (Exception ex) 
        //    {                
        //        log.Error("Failed to start ProcessEmailQueueTask at EmailService.AddEmailToQueue()", ex);
        //        // Ignore this error and continue; the task wil be started regularly
        //    }
        //}

        public static async Task SendMailNoQueueAsync(string from, IEnumerable to, string subject, string body)
        {
            var message = new MailMessage
            {
                Subject = subject,
                From = new MailAddress(@from),
                Body = body,
                BodyEncoding = Encoding.UTF8,
                IsBodyHtml = true
            };

            foreach (var address in to)
            {
                message.To.Add(address);
            }

            await SendMailNoQueueAsync(message);
        }

        public static async Task SendMailNoQueueAsync(MailMessage mailMessage)
        {
            using (var smtpClient = new SmtpClient(host, port))
            {
                await smtpClient.SendMailAsync(mailMessage);
            }
        }
    }
}
5380cookie-checkC# EmailService