/// <summary> /// Send mail to mailreceivers using System.Web.Mail /// </summary> /// <param name="mailInfo"></param> /// <param name="recipients"></param> /// <param name="testMode">No mails are sent, generating report for user</param> /// <returns>A SendMailLog object with information about the status of the job.</returns> public override SendMailLog SendEmail(MailInformation mailInfo, JobWorkItems recipients, bool testMode) { _log.Debug("900.10.11.1 Starting Send"); // for logging SendMailLog log = new SendMailLog(); log.StartJob(); // Recipients util RecipientsUtility recipUtil = new RecipientsUtility(); // We try to verify as many settings, variables etc. before // starting the sending loop, as we don't want to generate // lots of exceptions in a loop. // Need someone to send to if (recipients.Items.Count == 0) { _log.Error("900.10.11.2 Trying to send mail with an empty JobWorkItems collection. Please check the collection before attemting to send mail."); throw new ArgumentNullException("Recipient collection is empty, there is no recipients to send to.", "recepients"); } // And, we need a sender address if (mailInfo.From == null || mailInfo.From == string.Empty) { _log.Error("900.10.11.3 Missing from address. SMTP servers do not allow sending without a sender."); throw new ArgumentNullException("Missing from address. SMTP servers do not allow sending without a sender.", "mailInfo.From"); } // Load the license. This needs to be in the EmailMessage.LoadLicenseString(GetLicenseFileContents()); // We'll reuse the mail object, so we create it outside of the loop EmailMessage mail = CreateMessage(mailInfo); // Set port and authentication details if found InitializeMailSettings(ref mail); // Send a warm-up message outside the loop. This // will help us catch any misconfigurations and other // things that prevents us from sending emails. By // doing this outside the loop, we won't kill the // application or log with uneccesary error messages. // TODO: Implement this // Loop through receivers collection, send email for each foreach (JobWorkItem workItem in recipients) { _log.Debug(string.Format("900.10.11.5 Job {0}, Email: {1}, Status: {2}", workItem.JobId.ToString(), workItem.EmailAddress, workItem.Status.ToString())); // Only attempt sending those that have been stamped as ready for sending // unless we're in a test case. if (workItem.Status == JobWorkStatus.Sending || testMode == true) { try { // At this point we assume the address is formatted correctly // and checked, but aspNetEmail checks the to address on set, may fail mail.To = workItem.EmailAddress; // Perform actual send, if testmail, then this will // return false. We should not update the status on // test sends bool result = SendMail(mail, testMode); if (result == true) { log.SuccessMessages.Add(workItem.EmailAddress); // Update status and save it // TODO: Improve performance by doing this in batch workItem.Status = JobWorkStatus.Complete; // Only save if real work item (could be a test item) if (workItem.JobId > 0) { workItem.Save(); } } // else // Could not send, it has been disabled by // settings or parameters } catch (Exception ex) { _log.Error(string.Format("900.10.11.6 Error sending to email: {0}", workItem.EmailAddress), ex); string exceptionMsg = string.Format("Email: {0}\r\nException: {1}\r\n\r\n", workItem.EmailAddress, ex.Message); log.ErrorMessages.Add(exceptionMsg); // Update work item workItem.Status = JobWorkStatus.Failed; if (exceptionMsg.Length >= 2000) { exceptionMsg = exceptionMsg.Substring(0, 1999); } workItem.Info = exceptionMsg; if (workItem.JobId > 0) { workItem.Save(); } } } else { _log.Debug(string.Format("900.10.11.7 Skipping Recipient, wrong status. Job {0}, Email: {1}, Status: {2}", workItem.JobId.ToString(), workItem.EmailAddress, workItem.Status.ToString())); } } // Finished log.StopJob(); // Warn user if logging is enabled if (Configuration.NewsLetterConfiguration.ExtendedLogFile != null) { log.WarningMessages.Add("Logging has been enabled. Only use during troubleshooting."); } _log.Debug("900.10.11.8 Ending Send"); // return report return(log); }