UPDATE: Give a look at this new article about Helper Mailer class for template-based e-mail with embedded images.
Here I will propose a way to use UserControls as mail templates to easily compose HTML messages without the need to write each single tag by code.
Keep in mind you can use any UserControl, with any kind of child controls in it.
For example this could be an order confirmation mail, with a GriView bound to a DataTable.
Or perhaps a user registration email, using a FormView as a summary of the user's profile data.
I will use a simple UserControl with a single Label, just to show how the whole thing works.
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MailTemplate.ascx.cs" Inherits="TemplateMailer_MailTemplate" %>
Hello <asp:Label runat="server" ID="DestinationNameLabel" />,<br />
This is a UserControl-based mail template.
This is a UserControl like those we normally use in our web projects.
I am using here a Label as a placeholder for the destination name.
We could use as many such labels as needed in our template, or even Images, as long as their ImageUrl is set to absolute URLs.
Second step: declare an interface for our template.
public interface IMailTemplate
{
string DestinationName
{
get;
set;
}
}
We will access our template's field through this interface.
Let's modify our UserControl's codebehind to have it implement the IMailTemplate interface.
public partial class TemplateMailer_MailTemplate : System.Web.UI.UserControl, IMailTemplate
{
public string DestinationName
{
get
{
return DestinationNameLabel.Text;
}
set
{
DestinationNameLabel.Text = value;
}
}
}
Our DestinationName property gets and sets the value of the Label we used as a placeholder.
Finally, to complete this little magic, here is the code to create a MailMessage using HTML code generated by our template UserControl.
Say we have an ASPX page with a button to generate and send the e-mail.
This could be a simple implementation of its OnClick event handler:
protected void SubmitButton_Click(
object sender, EventArgs e)
{
Control mailTemplate = LoadControl(
"MailTemplate.ascx");
((IMailTemplate)mailTemplate).DestinationName = "Destination Name";
StringBuilder stringBuilder =
new StringBuilder();
StringWriter stringWriter =
new StringWriter(stringBuilder);
HtmlTextWriter htmlTextWriter =
new HtmlTextWriter(stringWriter);
mailTemplate.RenderControl(htmlTextWriter);
htmlTextWriter.Close();
string messageBody = stringBuilder.ToString();
MailMessage message =
new MailMessage(
"sender@domain.com",
"destination@domain.com");
message.IsBodyHtml =
true;
message.Body = messageBody;
SmtpClient client = new SmtpClient("pop3.server.com");
client.Send(message);
}
All the magic happens in the first lines of code.
We are dynamically loading our template UserControl invoking LoadControl method.
The UserControl is then casted to the IMailTemplate interface to get access to the DestinationName property and set it to whatever value we need (this could be read from a database, from a control in the page, etc).
We get then our HTML code by invoking the UserControl's RenderControl method, passing in an HtmlTextWriter bound to a StringWriter.
The StringWriter appends the rendered code to a StringBuilder.
Finally we set the MailMessage's body to the resulting text.
The message is sent through an SmtpClient object, as usual.
That's it. Hope you will find this useful!
Happy coding!