Skip to content

Placeholders and Variables

Norbert Bietsch edited this page Jun 14, 2018 · 5 revisions

Before creating a mail message it makes sense to think about what shall be the data source for replacing {placeholders} with variable values.

The data source can be any of the following types: Dictionary<string,object>, Dictionary<string,object>, ExpandoObject, DataRow, any class instances or anonymous types.

Singular Data

In each of the following samples the variable named variable can become the paramater in

var msg = new MailMergeMessage(...);
new MailMergeSender().Send(msg, variable);

All singular data target to one email message.

Dictionary

When using a Dictionary as the data source, the elements' Key will be the text for the {placeholder}, and the elements' Value will become the inserted string :

var variable = new Dictionary<string, string>() { { "Email", "[email protected]" } };

Note: Singular data of type Dictionary (and other IEnumerable) must be cast to an object.

JSON JObject

JSON comes in handy when processing data in a web api application where the argument submitted from the browser to the controller is a JObject.

When using a JObject as the data source, the tokens' Key will be the text for the {placeholder}, and the tokens' Value will become the inserted string :

var variable = JObject.Parse("{'Name':'John','Email':'[email protected]'}");

Anonymous Type

// an array of anonymous type
var variable =  new { Email = "[email protected]", Name = "John Specimen" };

Class

An advantage when using class instances: It's allowed to use the name of parameter less methods. In the follwing example {variables.FullName} is valid besides the class properties.

class Recipient
{
    public string Email { set; get; } = "[email protected]";
    public string Name { get; set; } = "John";
    public string LastName { get; set; } = "Sample";
    public string FullName() { return Name + " " + LastName; }
}
var variable = new Recipient();

ExpandoObject

dynamic variable = new ExpandoObject();
variable.Email = "[email protected]";
variable.Name = "John Specimen"

DataRow

DataTable table = new DataTable();
table.Columns.Add("Email", typeof(string));
table.Columns.Add("Name", typeof(string));
table.Rows.Add("[email protected]", "John Specimen");
var variable = table.Rows[0];

Plurality of Data

In each of the following samples the variable named several can become the paramater in

var msg = new MailMergeMessage(...);
new MailMergeSender().Send(msg, several);

For each record of the list a new mail message will be generated.

IEnumerable

In general, any object implementing IEnumerable is possible.

var several = new[]
{
	new { Email = "[email protected]", Name = "John Specimen" },
	new { Email = "[email protected]",   Name = "Mary Specimen" }
};

JSON JArray

JSON comes in handy when processing data in a web api application where the argument submitted from the browser to the controller is a JObject or JArray. JSON Arrays are also IEnumerable.

var several = JArray.Parse(@"
[
    { 'Email': '[email protected]', 'Name': 'John' },
    { 'Email': '[email protected]', 'Name': 'Mary' }
]
");

Another scenario is working with queries from SQL Server:

SELECT 'John' AS [FirstName], 'Doe' AS [LastName], '[email protected]' AS [Email]
FOR JSON PATH, ROOT('Newsletters')

DataRows

When using a DataTable the DataRows become the parameter.

DataTable table = new DataTable();
table.Columns.Add("Email", typeof(string));
table.Columns.Add("Name", typeof(string));
table.Rows.Add("[email protected]", "John Specimen");
table.Rows.Add("[email protected]", "Mary Specimen");
var several = table.Rows;

Dot Notation

Nested Classes or Anonymous Types

Lets assume we have the following classes.

class Recipient
{
    public string Email { set; get; }
    public string Name { get; set; }
    public Address Address { get; set; }
}
class Address
{
    public string PostalCode { set; get; }
    public string City { get; set; }
    public Address Street { get; set; }
}

If want to have the City member from an instance of Recipient, the {placeholder} would be {Recipient.Address.City}.

Nested Dictionaries

var variable = new Dictionary<string, object>()
{
    {"Recipient", new Dictionary<string, string>() {{"Email", "[email protected]"}, {"Name", "John Specimen"}}}
};

If you want to have the Email property, the {placeholder} would be {Recipient.Email} - just the same as with nest classes.

SmartObjects - Combine Several Data Sources

SmartObjects are a smart way to pass several data sources to the Send methods of a MailMergeSender. Any of the data types mentioned above can be combined in SmartObjects.

Example:

var d1 = new Dictionary<string,string> { {"myKey", "myValue"} };
var d2 = new Dictionary<string,string> { {"mySecondKey", "mySecondValue"} };
var smartObj = new SmartObjects();
smartObj.AddRange(new object[] {d1, d2});

// get the SmartFormatter which is used when processing message content
var smartFormatter = new MailMergeMessage().SmartFormatter;
var result = smartFormatter.Format("{myKey} - {mySecondKey}", smartObj);
// result: "myValue - mySecondValue"

Here is the analogy with a MailMergeMessage:

var mailMergeMessage = new MailMergeMessage("Some subject", "{myKey} - {mySecondKey}");
new MailMergeSender().Send(mailMergeMessage, smartObj);
// The plain text body of the message will read: 
// "myValue - mySecondValue"

Note 1:

In case more than one object has the same member (or key) name, the value of the first object in the list will prevail. Change the order of objects in the list to change the object priority. If d2 in the example above would also have "myKey" as the dictionary key - same as d1 - then the value of d2 would not be accessible within the SmartObjects.

Note 2:

In cases where mail messages shall be generated for a number of records, it is of course also allowed to to pass a List<SmartObjects> as a parameter to the send methods.