In medieval times, town criers were the primary means of making announcements to a community. Nowadays a man with a bell is a very imaginative – but not particularly practical – means of communication.
One common scenario, especially in the business world, is the need to send out an email to a large number of people. Of course a big anonymous email lacks the friendliness of the local loud-mouthed peasant and so we try to personalise the emails with individuals’ names etc.
I suspect most .NET developers have come across this problem at some point in their career. This generally leads to a lot of messy string concatenation and trying to manhandle the System.Net.Mail.SmtpClient into doing what you want. With text-based emails this is ugly, when HTML is involved it becomes a world of pain.
Town Crier is a project I have been working on to simplify this scenario. The basic workflow for sending a templated e-mail is as follows:
- Create an email template.
This can be either a plain-text or HTML file (or both). Tokens to be replaced are written like this: {%= customersname %} - Write some very simple code in the CLR language of your choice, in this case C#:
var factory = new MergedEmailFactory(new TemplateParser()); var tokenValues = new Dictionary<string, string> { {"name", "Joe Bloggs"}, {"age", "21"} }; MailMessage message = factory .WithTokenValues(tokenValues) .WithSubject("Test Subject") .WithHtmlBodyFromFile(@"templates\sample-email.html") .WithPlainTextBodyFromFile(@"templates\sample-email.txt") .Create(); var from = new MailAddress("sender@test.com", "Automated Emailer"); var to = new MailAddress("recipient@test.com", "Joe Bloggs"); message.From = from; message.To.Add(to); var smtpClient = new SmtpClient(); smtpClient.Send(message);
Of course it’s then trivial to loop through rows in a database, populate the dictionary and perform a “mail-merge” programatically.
One final handy tip – there is included a handy extension method to allow you to save the message to a .eml file:
message.Save(new FileStream(@"output.eml", FileMode.CreateNew));
That’s pretty much it! It’s fairly basic but I’ve found it to be very useful. It’s also my first open-source project so please be nice!
I am releasing it under the Lesser GNU Public Licence. Go grab the sources at GitHub.