Dot Net Tricks

Articles about .NET, ASP.NET, C#, Object Oriented Programming and Agile Methodologies
Welcome to Dot Net Tricks Sign in | Join | Help
in Search

Thoughts.Generate();

Creating Email Templates in Asp.net 2.0 using MailDefinition

This site's name is dot net tricks (dotNetTricks.com), so I guess I have to show a trick first. I'm taking some advice from Craig on Picking Low Hanging Fruit first, so I can get into a rhythm and hopefully have a couple posts a week.   

In the spirit of all things 2.0, I think I want to show how to leverage the built in email template functionality in ASP.net 2.0, called MailDefintion.  I don't believe I've ever seen a post on this, so this is sort of a good place to leverage some useful functionality that's really easy to use and you can build a pretty decent emailing templating system in a short time. 
The basis of this stems from the controls such as the CreateUserWizard Controls, which can send emails based on templates you define within the control.  I see it as a useful feature and really wished that this was exposed a bit more for consumption. 

 <asp:CreateUserWizard ID="CreateUserWizard1" Runat="server">
   <MailDefinition 
     BodyFileName="~/RegistrationEmail.txt" 
     From="http://nettiers.com"
     Subject="Thanks for registering!">
   </MailDefinition>
</asp:CreateUserWizard>

So, I took a look at that and said, hey, why are the membership controls the only ones that can define a MailDefinition, I want to use that in my controls too.  So, a few minutes with Reflector  told me how the controls levered the functionality that I wanted as well.
The calling code ends up looking this:

ListDictionary replacements = new ListDictionary();
replacements.Add("<%UserName%>", userName);
replacements.Add("<%TeamMember%>", teamMember); 

// it can only be used in the context of a control, so I usually send over the control responsible for the tirggering event.
bool emailSent = WebNotificationManager.SendMessage(btnSubmitEmail, MessageTemplate.DownloadInstructions, replacements,
    userEmail, Resources.MailSubject.DownloadSubject);


Then the control automagically fires off that email based on settings you put in the web.config.

    <system.net>
        <mailSettings>
            <smtp from=“info@nettiers.com”>
                <network host=“mail.nettiers.com” userName=email@name.com password="somepass" />
                </smtp>
            </mailSettings>
    </system.net>

For ease of use, I created a MessageTemplate enumeration to hold all of the templates that exists in the application, this could live in the DB as well, it didn't make sense in the application I was writing at the time.

    /// <summary>
    /// Summary description for MessageTemplate
    /// </summary>
    public enum MessageTemplate 
    {
        None,
        ThankYouForVisiting,
        DownloadInstructions
   }

For this example I'm going to use the DownloadInstructions template which looks like this.
~/App_Data/DownloadInstructions.txt

Hi <%UserName%>,

Please download .netTiers at www.nettiers.com.

Thank you,

<%TeamMember%>
.netTiers Team

Really now you get it to work by creating a MailDefinition in code based on your template you provide.
public static bool SendMessage(WebControl owner, MessageTemplate messageTemplate, ListDictionary replacements, string to, string subject)
{
    MailMessage mailMessage = CreateMessage(owner, messageTemplate, replacements, to, null, null, subject);
    return InternalSend(mailMessage);
}

private static System.Net.Mail.MailMessage CreateMessage(WebControl owner, MessageTemplate messageTemplate, ListDictionary replacements, string to, string from, string cc, string subject)
{
    string physicalPath = HttpContext.Current.Server.MapPath("~/App_Data/messages/" + messageTemplate.ToString() + ".txt");

    if (!File.Exists(physicalPath))
    {
        throw new ArgumentException("Invalid MailTemplate Passed into the NotificationManager", "messageTemplate");
    }

    MailDefinition md = new MailDefinition();
    md.BodyFileName = physicalPath;
    md.Subject = subject;
    md.From = from;
    md.CC = cc;
    md.IsBodyHtml = false;

    System.Net.Mail.MailMessage mailMessage;
//this actually processes all of the replacement vars that you've included. mailMessage = md.CreateMailMessage(to, replacements, owner); return mailMessage; }


There are many ways to sending the actual email, it's not that glamorous, but i'm including the code anyway so that this example will be feature complete.
private static bool InternalSend(MailMessage mailMessage, bool isAsync)
{
    try
    {
        if (!isAsync)  // blocks current thread
            WebMailSender.SendMailMessage(mailMessage);
        else  // does not block current thread
            WebMailSender.SendMailMessageAsync(mailMessage);
    }
    catch (Exception exc)
    {  
       //handle, log, do something
        throw;
    }
    return true;
}

public static bool SendMailMessage(MailMessage mailMessage)
{
    try
    {
        SmtpClient client = new SmtpClient();
        client.Send(mailMessage);
    }
    catch (Exception exc)
    {
      // Log
        throw;
    }
    return true;
}

public static void SendMailMessageAsync(MailMessage mailMessage)
{
    try
    {
        SmtpClient client = new SmtpClient();
        client.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback);
        client.SendAsync(mailMessage, mailMessage.To.ToString());
    }
    catch (Exception)
    {
        //Log
        throw;
    }
}

Published Friday, May 12, 2006 9:47 PM by rhinojosa
Filed Under:

Comments

No Comments
Anonymous comments are disabled

About rhinojosa

My thoughts on software principles, code generation, business practices, and the technology climate of today. Developer on the open source .netTiers code generation suite of templates! www.nettiers.com Get your copy today, or view a 15 minute video tutorial! http://www.codeproject.com/showcase/CodeSmith.asp

This Blog

Post Calendar

<May 2006>
SuMoTuWeThFrSa
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

Syndication

Powered by Community Server, by Telligent Systems