SmtpAddJob Method (String, String, EmailAddressCollection, DataTable)
Puts a "mail merge over database" job onto waiting list for subsequent processing in bulk mode.

Namespace: MailBee.SmtpMail
Assembly: MailBee.NET (in MailBee.NET.dll) Version: 12.3.1 build 666 for .NET 4.5
public void AddJob(
	string tag,
	string senderEmailPattern,
	EmailAddressCollection recipientsPattern,
	DataTable mergeTable


Type: SystemString
Any string the developer wants to assign to Tag property of SendMailJob object created by this method. The developer can leave it a null reference (Nothing in Visual Basic).
Type: SystemString
The e-mail address template of the sender. If it's a null reference (Nothing in Visual Basic), the e-mail address template will be taken from From property.
Type: MailBee.MimeEmailAddressCollection
The e-mail address template of the recipients list. If it's a null reference (Nothing in Visual Basic), the recipients list will be constructed via merge of To, Cc, and Bcc patterns with actual values from the data source.
Type: System.DataDataTable
The data source for mail merge.
MailBeeInvalidArgumentExceptionmergeTable is a null reference (Nothing in Visual Basic).

This method allows the application to schedule mail merge over database for subsequent processing with SendJobs, BeginSendJobs(AsyncCallback, Object), or SubmitJobsToPickupFolder(String, Boolean) method.

Note Note
To perform mail merge immediately rather than schedule it, use SendMailMerge(String, EmailAddressCollection, DataTable) method.
Note Note
This method is not available in .NET Core and UWP editions.

The mail merge requirements:

  • The template of e-mail to be merged with mergeTable data must be specified in Message property. Normally, Message property specifies the e-mail message to be sent out by Smtp object. In the case of mail merge, this e-mail message is considered as a template where ##Column_Name## patterns will be replaced with the actual data from database table rows during the mail merge process.
  • Smtp.DeliveryNotification.TrackingID may also contain a pattern if desired. Thus, it's possible to automatically assign unique tracking ID to the each message sent during mail merge and then receive this ID with bounced messages.
  • mergeTable must be the data source containing all the data rows for which e-mails should be generated and sent; typically, this data source is a result of SQL query.
  • Names of columns of mergeTable must match pattern names in the e-mail template. For instance, if there is Email column in the data table and the developer wishes to make values from this column appear in resulting e-mails, then the e-mail template must contain ##Email## string in the places where the e-mail address needs to be placed. Patterns are case-sensitive! For instance, if data table column name is Email, only ##Email## pattern will be replaced with the column value. ##email## and ##EMAIL## patterns will be left intact.
  • senderEmailPattern can be left null. However, if resulting e-mails should actually be sent from another e-mail address (for instance, resulting e-mails have in "From:" field while you wish to send them from ""), then it's required to specify senderEmailPattern. It can contain a pattern (e.g. ##Something##) or refer to the actual value (e.g.
  • recipientsPattern have the same meaning for specifying the actual recipients as senderEmailPattern - for the actual sender. For instance, to set the pattern which will take the 1st recipient's e-mail address from Email field of the data table while the 2nd recipient's email address is hard-coded, pass the following as recipientsPattern value: new EmailAddressCollection("##Email##,").
  • Setting tag to non-empty value helps to distinguish the current mail merge from other jobs if there are any. This is useful if the application submits and processes multiple jobs and the developer wants to track processing of each job separately. Jobs tags also appear in the log if logging is enabled.

Calling this overload is equivalent to calling AddJob(String, String, EmailAddressCollection, DataTable, Object, Boolean, Boolean) with mergeRowIndices set to null, keepProducedJobs set to true, and keepMergedData set to false.

This console sample sends out 2 newsletters based on the same database table and different e-mail templates. Both newsletters are sent out from the same sender to the same recipients. The first newsletter is more complex and may contain attachments. The second newsletter is simpler.
using System;
using System.Data;
using System.Data.OleDb;
using MailBee;
using MailBee.Mime;
using MailBee.SmtpMail;

class Sample
    // Occurs when an e-mail message is ready to be sent.
    static void mailer_SendingMessage(object sender, SmtpSendingMessageEventArgs e)
        // Display e-mail address of the e-mail to be sent.
        Console.WriteLine(e.MergeTable.Rows[e.MergeRowIndex]["Email"] + " of '" + e.Tag + "'");

        // You can also subscribe to events like MergingMessage, MessageSent, MessageNotSent
        // to keep the detailed track of mail merge progress.

    static void Main(string[] args)
        Smtp mailer = new Smtp();

        // Logging into a file is useful for troubleshooting.
        mailer.Log.Filename = @"C:\Temp\log.txt";
        mailer.Log.Enabled = true;
        mailer.Log.Format = LogFormatOptions.AddContextInfo;

        // Uncomment the line below to use unlimited number of worker threads (up to 60)
        // and increase performance. Note that not all SMTP servers support this.

        // mailer.MaxThreadCount = -1;

        // Subscribe to event to track send bulk mail progress.
        mailer.SendingMessage += new SmtpSendingMessageEventHandler(mailer_SendingMessage);

        // Setup SMTP server parameters.
        mailer.SmtpServers.Add("", "jdoe", "secret");

        // Setup e-mail message header template for mail merge.
        mailer.Message.From.AsString = "John Doe <>";
        mailer.Message.To.AsString = "##Name## <##Email##>";
        mailer.Message.Subject = "Our newsletter";

        // Setup DSN template for mail merge. In particular, this can be useful
        // to track bounced messages which may come back from some addresses after
        // sending bulk mail out. If the SMTP server does not support DSN, this
        // setting will be ignored.
        mailer.DeliveryNotification.TrackingID = "##ID##-N";

        // Setup HTML body template.
        mailer.Message.BodyHtmlText = "<html>##Body##</html>";

        // Setup template for adding file attachments upon the specified path.
        // In this sample, the path to attachment files will be constructed as
        // "C:\" + DatabaseRecordField("Doc_path").

        // Make outgoing e-mails UTF-8 to allow content in any language.
        mailer.Message.Charset = "UTF-8";

        // Tell MailBee to generate alternative plain-text version
        // of each e-mail automatically.
        mailer.Message.Builder.HtmlToPlainMode = HtmlToPlainAutoConvert.IfHtml;

        // Specify database connection string (it may be different in your case).
        string connParams = @"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=C:\Temp\newsletter.mdb;";

        DataTable table = new DataTable();

        // Connect to the database and populate mail merge job to-do list with
        // the data from "mailing_list" table.
        using (OleDbConnection conn = new OleDbConnection(connParams))
            // Open the connection and get the data.
            OleDbCommand command = new OleDbCommand("SELECT * FROM mailing_list", conn);
            OleDbDataAdapter adapter = new OleDbDataAdapter();
            adapter.SelectCommand = command;

            // Create a job which is the following task for MailBee: perform mail merge
            // of a newsletter template with data rows of the specified data table and
            // send out each resulting e-mail to its intended recipients.
            mailer.AddJob("Newsletter #1", null, null, table);

            // Change template parameters for another newsletter.
            mailer.Message.Subject = "Newsletter update";

            // Setup DSN template for mail merge. In particular, this can be useful
            // to track bounced messages which may come back from some addresses after
            // sending bulk mail out. If the SMTP server does not support DSN, this
            // setting will be ignored.
            mailer.DeliveryNotification.TrackingID = "##ID##-NU";

            // Setup HTML body template.
            mailer.Message.BodyHtmlText = "<html>Please disregard the newsletter you just received.</html>";

            // If we do not want attachments in second newsletter, remove the pattern.

            // Create a job of sending another newsletter to the same recipients.
            mailer.AddJob("Newsletter #2", null, null, table);

        // Run the jobs. The actual mail merge takes place here.

        // Report results (row indices in the data table) to the console.
        if (mailer.JobsFailed.Count == 0)
            Console.WriteLine("Both newsletters have been sent out without any errors.");
            if (mailer.JobsSuccessful.Count == 0)
                Console.WriteLine("All newsletter e-mails failed to be sent.");
                Console.WriteLine("Not all newsletter e-mails have been sent.");

                Console.WriteLine("Successful rows (Our newsletter): ");
                Console.WriteLine(mailer.JobsSuccessful.GetIndicesAsString(table, "Newsletter #1"));

                Console.WriteLine("Failed rows (Our newsletter): ");
                Console.WriteLine(mailer.JobsFailed.GetIndicesAsString(table, "Newsletter #1"));

                Console.WriteLine("Successful rows (Newsletter update): ");
                Console.WriteLine(mailer.JobsSuccessful.GetIndicesAsString(table, "Newsletter #2"));

                Console.WriteLine("Failed rows (Newsletter update): ");
                Console.WriteLine(mailer.JobsFailed.GetIndicesAsString(table, "Newsletter #2"));
See Also