-
Notifications
You must be signed in to change notification settings - Fork 32
Placeholders and Variables
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.
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.
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", "sample@example.com" } };Note: Singular data of type Dictionary (and other IEnumerable) must be cast to an object.
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':'sample@example.com'}");// an array of anonymous type
var variable = new { Email = "sample@example.com", Name = "John Specimen" };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; } = "test@example.com";
public string Name { get; set; } = "John";
public string LastName { get; set; } = "Sample";
public string FullName() { return Name + " " + LastName; }
}
var variable = new Recipient();dynamic variable = new ExpandoObject();
variable.Email = "sample@example.com";
variable.Name = "John Specimen"DataTable table = new DataTable();
table.Columns.Add("Email", typeof(string));
table.Columns.Add("Name", typeof(string));
table.Rows.Add("sample@example.com", "John Specimen");
var variable = table.Rows[0];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.
In general, any object implementing IEnumerable is possible.
var several = new[]
{
new { Email = "sample@example.com", Name = "John Specimen" },
new { Email = "mary@example.com", Name = "Mary Specimen" }
};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.1@example.com', 'Name': 'John' },
{ 'Email': 'email.2@example.com', 'Name': 'Mary' }
]
");Another scenario is working with queries from SQL Server:
SELECT 'John' AS [FirstName], 'Doe' AS [LastName], 'email@example.com' AS [Email]
FOR JSON PATH, ROOT('Newsletters')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("sample@example.com", "John Specimen");
table.Rows.Add("mary@example.com", "Mary Specimen");
var several = table.Rows;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}.
var variable = new Dictionary<string, object>()
{
{"Recipient", new Dictionary<string, string>() {{"Email", "sample@example.com"}, {"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 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.