MailHelper Class
This class provides the core foundation for the mail processing architecture by exposing a method named SendMail that basically performs the core operation. When a client component wants to send mail, it creates an instance of the MailAttributeCollection class and populates its properties with appropriate values. Then it invokes the SendMail method of MailHelper class passing in the populated MailAttributeCollection object. Apart from the MailAttributeCollection class, it also passes an enum constant named MailTemplate that indicates the type of mail that needs to be sent out. For example, to send out mail that is related to the products, the value MailTemplate.ProductInformation is passed in as a parameter.
using System;
using System.Xml;
using System.Xml.Xsl;
using System.IO;
using System.Web.Mail;
using System.Data;
using
System.Data.SqlClient;
namespace
MailProcessingLib
{
public class MailHelper
{
public MailHelper()
{
}
As mentioned before, the SendMail method takes a MailAttributeCollection object and a MailTemplate enum constant as its arguments.
public
void SendMail(MailTemplate template,
MailAttributeCollection
mailAttrCollection)
{
In the following line, it creates an instance of the AppSettingsReader object that is used to read the configuration settings from a configuration file.
System.Configuration.AppSettingsReader
configurationAppSettings
= new
System.Configuration.AppSettingsReader();
All the configuration settings required for mail processing are stored in a file named app.config. This file is part of the client application that invokes the mail processing component. When invoked, the mail processing component automatically reads the settings from the client configuration file. The configuration settings are defined as follows in the app.config file.
<?xml version="1.0" encoding="Windows-1252"?>
<configuration>
<appSettings>
<add key="fromMailAddress" value="test@test.com" />
<add key="stylesheetLocation" value="D:\My Programs\15Seconds\Efficent
Mail Processing\MailProcessingLib\Stylesheets" />
<add key="attachmentsLocation" value="D:\My Programs\15Seconds\Efficent
Mail Processing\MailProcessingLib\Attachments" />
<add key="connectionString"
value="server=localhost;uid=sa;pwd=thiru;database=15Seconds;" />
</appSettings>
</configuration>
To retrieve the value of the element fromMailAddress from the configuration file, you need to add the following line of code.
//Get
the From EMail Address
string fromMailAddress =
string)(configurationAppSettings.GetValue("fromMailAddress",
typeof(string))));
Then we convert the attributes contained in the MailAttributeCollection object to a dynamic XML string using a private Helper method named CreateXmlDocument.
//Convert the MailAttributeCollection object into an xml
document object that can be used for transformation
XmlDocument
xmlDoc = CreateXmlDocument(mailAttrCollection);
string
xslStlyesheet;
Here we evaluate the value of the enum constant MailTemplate to determine the XSL stylesheet to load in the memory.
//Determine the stylesheet to be used for transformation
switch (template)
{
case MailTemplate.CategoriesInformation:
xslStlyesheet
= "CategoriesInformation.xsl";
break;
case MailTemplate.ProductsInformation:
xslStlyesheet
= "ProductsInformation.xsl";
break;
default:
/Assign the CategoriesInformation.xsl as the
default stylesheet
xslStlyesheet
= "CategoriesInformation.xsl";
break;
}
After that, we load the XSL stylesheet onto the memory by appending the value of the location of the stylesheet (that is retrieved from the configuration file) with the name of the stylesheet. To accomplish this, we use the Load method of the XslTransform object.
XslTransform
transform = new XslTransform(); //Get the stylesheets folder location from the
configuration file
string
stylesheetDirectory = ((string)(configurationAppSettings.GetValue
("stylesheetLocation",
typeof(string))));
//Load the stylesheet into the memory
transform.Load(stylesheetDirectory
+ "\\" +
xslStlyesheet);
Once the stylesheet is loaded onto the memory, we can then easily transform the XML contents to an HTML document by applying XML and XSL. To do this, we need to pass in the XmlDocument object that is created from the CreateXmlDocument method as well as a StringWriter object to the Transform method of XslTransform object. The Transform method combines XML with XSL and stores the resultant HTML document in the StringWriter object that is passed in as an argument.
//Create an instance of StringWriter object to hold the
transformed HTML
StringWriter
writer = new StringWriter();
//Transform the xml contents into HTML by applying the
stylesheet
transform.Transform(xmlDoc,null,writer);
//Get the body of the mail from the StringWriter object
string body = writer.ToString();
Finally we save the body of the mail as well as all the related mail attributes such as ToList, CCList, BccList and so on to a Sql Server table by invoking the private helper method named SaveMail.
SaveMail(fromMailAddress,mailAttrCollection.ToList,
mailAttrCollection.CCList, mailAttrCollection.BccList,mailAttrCollection.Subject, (int)mailAttrCollection.Priority,body,
mailAttrCollection.Attachments);
XSL Files
As mentioned before, we use XSL to create the presentation for the body of the mail. One of the main advantages of using XSL is that we can easily change the contents of the mail if there is a need to do so. To change the presentation of the mail, all you need to do is modify the XSL file without even having to touch the code that sends out mail. This provides us with an extensible approach that can be very useful in maintaining the application, especially considering the drastic changes that are likely to happen in the business process. Another advantage of using XSL is that if you want to send a different type of mail (For example, a text-based mail) instead of an HTML based mail, all you need to do is change the XSL file. For the purposes of this article, two XSL files named ProductsInformation.xsl and CategoriesInformation.xsl are used. You can download the XSL files along with the code for the mail processing component from the 15Seconds Web site.
CreateXmlDocument Method
The CreateXmlDocument method takes in the MailAttributeCollection object as its argument. It starts off by creating an instance of the XmlDocument object that is used to hold the XML string. Then it creates a root XML node named MailRoot under which it adds all the attributes of the MailAttributeCollection object as child elements. Finally it returns the XmlDocument object back to the calling method.
private XmlDocument
CreateXmlDocument(MailAttributeCollection mailAttrContainer)
{
//Create an instance of XmlDocument
XmlDocument
xmlDoc = new XmlDocument();
//Create a root node that acts as the parent for all the
nodes
XmlNode
rootNode =
In the following line, it creates a node named MailRoot that acts as a parent node under which all the attributes of the MailAttributeCollection object are stored.
xmlDoc.CreateNode(XmlNodeType.Element,"MailRoot",null);
XmlNode
childNode;
Once the root node is created, it then creates all the remaining nodes such as Name, Address, State, Zip and so on and adds them to the root node.
//Create User Details under the root node
childNode
= xmlDoc.CreateNode(XmlNodeType.Element,"Name",null); childNode.InnerText
= mailAttrContainer.Name;
rootNode.AppendChild(childNode);
childNode
=
xmlDoc.CreateNode(XmlNodeType.Element,"Address",null); childNode.InnerText
= mailAttrContainer.Address;
rootNode.AppendChild(childNode);
childNode
=
xmlDoc.CreateNode(XmlNodeType.Element,"State",null); childNode.InnerText
= mailAttrContainer.State;
rootNode.AppendChild(childNode);
childNode
=
xmlDoc.CreateNode(XmlNodeType.Element,"Zip",null); childNode.InnerText
= mailAttrContainer.Zip;
rootNode.AppendChild(childNode);
//Create Recipient details
childNode
=
xmlDoc.CreateNode(XmlNodeType.Element,"ProductName",null); childNode.InnerText
= mailAttrContainer.ProductName;
rootNode.AppendChild(childNode);
childNode
=
xmlDoc.CreateNode(XmlNodeType.Element,"ProductDescription",null); childNode.InnerText
= mailAttrContainer.ProductDescription;
rootNode.AppendChild(childNode);
childNode =
xmlDoc.CreateNode(XmlNodeType.Element,"CategoryName",null);
childNode.InnerText
= mailAttrContainer.CategoryName;
rootNode.AppendChild(childNode);
//Add all the dates
childNode =
xmlDoc.CreateNode(XmlNodeType.Element,"CategoryDescription",null);
childNode.InnerText
= mailAttrContainer.CategoryDescription;
rootNode.AppendChild(childNode);
Finally it appends the root node to the previously created XmlDocument object and returns it back to the calling method.
xmlDoc.AppendChild(rootNode);
//Return the created XmlDocument object to the caller
return xmlDoc;