public static ServiceResponse ComposeMail(IUnitOfWork uow, MailComposeRequest request, string requestRootUrl, string overrideDisplayName = null) { request.CheckNotNull(); Check.NotNull(request.To, "to"); var config = Config.Get <MailSettings>(); var message = new MimeMessage(); var row = new Entities.MailRow(); row.Uid = Guid.NewGuid().ToString("N"); message.MessageId = row.Uid; var subject = "Mobility Matters | " + request.Subject ?? ""; string editLink = null; string editKind = null; row.Subject = subject; message.Subject = subject; if (config.SenderAddress.IsTrimmedEmpty()) { throw new ValidationError("Please set EmailSendAddress site setting!"); } var user = Authorization.UserDefinition as UserDefinition; var from = new MailboxAddress(overrideDisplayName ?? user.DisplayName, config.SenderAddress); row.From = from.ToString(); message.From.Add(from); var c = Entities.EmployeesRow.Fields; row.To = ""; foreach (var toId in request.To) { var toVolunteers = uow.Connection.ById <Entities.EmployeesRow>(toId, q => q .Select(c.FirstName) .Select(c.LastName) .Select(c.Email)); if (string.IsNullOrWhiteSpace(toVolunteers.Email)) { throw new ValidationError("To Volunteer " + toVolunteers.FirstName + " " + toVolunteers.LastName + " doesn't have an e-mail address, please set it!"); } var to = new MailboxAddress(toVolunteers.FirstName + " " + toVolunteers.LastName, toVolunteers.Email); row.To = row.To + ";" + to.ToString(); message.To.Add(to); } if (request.Cc != null) { var ccList = new List <string>(); foreach (var contactId in request.Cc) { var ccVolunteers = uow.Connection.ById <Entities.EmployeesRow>(contactId, q => q .Select(c.FirstName) .Select(c.LastName) .Select(c.Email)); if (ccVolunteers.Email.IsTrimmedEmpty()) { throw new ValidationError("CC Volunteer " + ccVolunteers.FirstName + " " + ccVolunteers.LastName + " doesn't have an e-mail address, please set it!"); } var cc = new MailboxAddress(ccVolunteers.FirstName + " " + ccVolunteers.LastName, ccVolunteers.Email); message.Cc.Add(cc); ccList.Add(cc.ToString()); } row.Cc = string.Join("; ", ccList); } var body = request.BodyHtml ?? ""; if (body.IndexOf("</html>") < 0) { body = "<html><title>" + HttpUtility.HtmlEncode(request.Subject) + "</title><body>" + body + "</body></html>"; } if (editLink != null) { var externalUrl = Config.Get <EnvironmentSettings>().SiteExternalUrl ?? requestRootUrl + VirtualPathUtility.ToAbsolute("~/"); editLink = HttpUtility.HtmlAttributeEncode(UriHelper.Combine(externalUrl, editLink)); var idx = body.IndexOf("</body>"); body = body.Insert(idx, "<p></p><p style=\"margin-top: 15px;\">Click link below to open related " + editKind + ":</p>" + "<p><a href=\"" + editLink + "\">" + HttpUtility.HtmlEncode(editLink) + "</a></p>"); } var bodyBuilder = new BodyBuilder(); body = AttachEmbeddedImages(bodyBuilder, body); var filesToDelete = new FilesToDelete(); UploadHelper.RegisterFilesToDelete(uow, filesToDelete); string fileNameFormat = "Northwind/Mail/{3:yyyyMM}/{4}"; var attachmentRows = AttachFiles(bodyBuilder, request.Attachments, filesToDelete, fileNameFormat); bodyBuilder.HtmlBody = body; row.Body = ConvertEmbeddedImagesToDataUris(bodyBuilder, body); message.Body = bodyBuilder.ToMessageBody(); row.Direction = "o"; row.SendDateTime = DateTime.UtcNow; row.CreatedBy = user?.UserId ?? user.UserId; row.CreatedOn = DateTime.UtcNow; var rowId = Convert.ToInt32(uow.Connection.InsertAndGetID(row)); foreach (var att in attachmentRows) { att.MailId = rowId; att.CreatedBy = row.CreatedBy; att.CreatedOn = DateTime.UtcNow; uow.Connection.Insert(att); } var response = new ServiceResponse(); uow.OnCommit += (() => { UsingSmtp(client => { try { client.Send(message); uow.Connection.UpdateById <Entities.MailRow>(new MyRow { MailId = rowId, IsSent = true }); } catch (Exception ex) { ex.Log(); uow.Connection.UpdateById <Entities.MailRow>(new MyRow { MailId = rowId, IsSent = false, ErrorMessage = ex.Message }); } }); UsingClient(client => { try { client.GetFolder(SpecialFolder.Sent).Append(message, MessageFlags.Seen); } catch (Exception ex) { ex.Log(); } }); }); return(response); }