Introduction
In this article, I am going to explain one of my class libraries that I developed for our projects. I have coded it in C# using Visual Studio 2008. Most of our .NET applications have email notifications, for example in registration process, online ordering, forums and blogs, etc.
I thought of an idea to manage the part of the email notification development in our projects. The code is very simple but the idea is nice and the developers really liked it. The idea is when the developers want to have an email notification functionality in their applications, instead of hard-coding the email body text within their code, or using resource files to build up their email messages, they can use that DLL which will allow them to specify the email template file and pass whatever parameters they like to build up their messages. This way, they will have the following advantages:
- They can manage their email templates any time without referring to the source code
- One single function for multiple email templates and multiple languages.
Using the Code
First of all, let me explain the emailing class. The source code is already attached in this article and is commented too. But here I would like to highlight the main functions.
The function that will format the email templates file and send the email is "SendNotificationEmail
". See the code below:
public string SendNotificationEmail(string EmailTemplateFile,
string SenderEmail, string SenderName, string RecepientEmail,
string CC, string Subject, params string[] Args)
{
string retVal = null;
string FileContents = ReadEmailFile(EmailTemplateFile);
string emailBody = emailheader() + FileContents + emailfooter();
retVal = string.Format(emailBody, Args);
try
{
if (!_debugmode)
SendEmail(SenderEmail, SenderName, RecepientEmail, CC,
(!string.IsNullOrEmpty(Subject) ? Subject : _subject), retVal);
}
catch (Exception ex)
{
throw ex;
}
return retVal;
}
In the function, note the line:
string FileContents = ReadEmailFile(EmailTemplateFile);
This function is the one that reads the template file passed by the user. See the function below:
protected string ReadEmailFile(string FileName)
{
string retVal = null;
try
{
string path = _TemplatesPath + FileName;
if (!File.Exists(path))
throw new Exception("Could Not Find the file : " + FileName +
" in the location " + _TemplatesPath);
StreamReader sr = new StreamReader(@path, System.Text.Encoding.GetEncoding(1256));
retVal = sr.ReadToEnd();
sr.Close();
}
catch (Exception ex)
{
throw new Exception("Error Reading File." + ex.Message);
}
return retVal;
}
Going back to the function "SendNotificationEmail
". We will read the email template and concatenate with the email header and email footer. Then we will use the string.Format
method to format our email message. See the code below:
string emailBody = emailheader() + FileContents + emailfooter();
retVal = string.Format(emailBody, Args);
The "emailheader()
" and "emailfooter()
" are private
functions just to read a default email header and footer from hard-coded files "email_header.txt" and "email_footer.txt". The reason why I am doing this is to make it easy to customize our email templates so that if we have 10 email templates sharing the same header and footer, and want to change something in the header or footer, we are changing in a single file.
See the functions code here:
protected string emailheader()
{
string retVal = null;
if (File.Exists(_TemplatesPath + "email_header.txt"))
{
retVal = ReadEmailFile("email_header.txt");
}
else
throw new Exception("you should have a file called
'email_header.txt' in the location :" + _TemplatesPath);
return retVal;
}
protected string emailfooter()
{
string retVal = null;
if (File.Exists(_TemplatesPath + "email_footer.txt"))
retVal = ReadEmailFile("email_footer.txt");
else
throw new Exception("you should have a file called
'email_footer.txt' in the location :" + _TemplatesPath);
return retVal;
}
Again, going back to the "SendNotificationEmail
". The last part of it after formatting the email message, we will send only if it is not in debug mode, otherwise, it will only return the email message in a string
. See the code below:
if (!_debugmode)
SendEmail(SenderEmail, SenderName, RecepientEmail, CC,
(!string.IsNullOrEmpty(Subject) ? Subject : _subject), retVal);
"SendEmail
" function is here:
protected void SendEmail(string SenderEmail, string SenderName,
string Recep, string cc, string email_title, string email_body)
{
MailMessage msg = new MailMessage();
msg.IsBodyHtml = true;
msg.From = new MailAddress(SenderEmail, SenderName);
msg.To.Add(Recep);
if (!string.IsNullOrEmpty(cc))
msg.CC.Add(cc);
msg.Subject = email_title;
msg.Body = email_body;
SmtpClient SmtpMail = new SmtpClient();
SmtpMail.Send(msg);
}
The constructor function, variable and properties. See the code:
#region Variabls
protected string _subject = null;
protected string _TemplatesPath = null;
protected bool _debugmode = false;
#endregion
public string EmailSubject
{
set { _subject = value; }
}
public bool DebugMode
{
set { _debugmode = value; }
}
public EmaislNotifications(string EmailHeaderSubject, string TemplatesPath)
{
_subject = EmailHeaderSubject;
_TemplatesPath = TemplatesPath;
}
Using DLL in an ASP.NET Application
Before I explain how to use the DLL, for demo purposes, I have created three TXT files and saved them to the "d:\emailing" folder in our web server. The files are:
email_header.txt
email_footer.txt
register.txt
Note that in the files, you can see the {0}, {1}, {2} and so on. Those will be substituted by the parameters argument passed by the user to the function.
So, in my ASPX page, I have a button, the onclick
event is:
EmaislNotifications en = new EmaislNotifications
("Registration", ConfigurationManager.AppSettings["EmailTemplatesPath"]);
#if (debug)
en.DebugMode = true;
Literal1.Text = en.SendNotificationEmail
("register.txt", "sender@company.com", "
Demo", "recep@company.com", null, "Registration",
ConfigurationManager.AppSettings["CompanyLogoURL"],
DateTime.Now.ToString("dddd dd, MMMM, yyyy"), "
Hussain Attiya", "hussain.attiya", "991001");
#endif
I have defined the following appSetting
keys in the web.config:
<appSettings>
<add key ="EmailTemplatesPath" value ="d:\emails\"/>
<add key ="CompanyLogoURL" value ="http://www.alhawaj.com/en/images/alhawaj_logo.gif"/>
</appSettings >
Also, the email setting needs to be defined in the web.config:
<system.net>
<mailSettings>
<smtp from="noreply@companydomain.com">
<network host="mail.companydomain.com" userName="xxx" password="xxx" port="25"/>
</smtp>
</mailSettings>
</system.net>
This is the resulted email message:
History
- 4th November, 2009: Initial post