Send Mails from within a .NET 2.0 Application

Most enterprise applications today need to send mail. This means the platform should provide the necessary support for applications to send these mails. In the case of .NET applications, .NET provides excellent support for sending e-mails through a set of intuitive classes. This article introduces the new ways of sending mails through the System.Net.Mail namespace by showing examples. You also will see the steps involved in sending attachments as part of the mails, as well as sending mails to multiple recipients in the form of CC and BCC lists. Finally, it explains the use of XML and XSL in formatting the bodies of HTML-based mails.

.NET 2.0 Mail Functions

Microsoft made some interesting changes in how you can send e-mail in version 2.0 of the .NET Framework. With .NET 1.x versions, you had to utilize the classes contained in the System.Web.Mail namespace for sending mails. Now, with the release of .NET 2.0, the System.Web.Mail namespace is obsolete and its functionality is now available in the System.Net.Mail namespace. This is a welcome change because the mail functionality was intended to be used for all .NET applications and should not have been under System.Web assembly.

In addition to moving the functionality under the System.Net.Mail namespace, the .NET team also completely rebuilt the implementation of SMTP functionality. There are new classes, properties, and methods that provide an elegant and clean way of performing operations related to sending mails. This long list of new enhancements includes quality improvements, different methods, and asynchronous support out of the box.

Now that you have a general understanding of the support provided by .NET 2.0 for sending mails, let us dive deep into the actual classes contained in the System.Net.Mail namespace.

System.Net.Mail Namespace

The System.Net.Mail namespace contains all the classes required for sending mail from within a .NET application. The classes contained in this namespace work a bit differently from the classes in the Web namespace. Table 1 describes the classes contained in the System.Net.Mail namespace.

Table 1. Important Classes in the System.Net.Mail Namespace

ClassDescription
Attachment Represents an attachment that is sent with a mail and is used in conjunction with the MailMessage class
MailAddress Represents the address of the sender or recipient (To, CC, and BCC)
MailMessage Represents an e-mail message that can be sent using the SmtpClient class and exposes properties such as From, To, CC, BCC, Attachments, Subject, and Body to formulate the message's contents
SmtpClient Allows applications to send emails using the SMTP
SmtpException Represents the exception that is thrown when the SmtpClient is not able to send the message

Of the classes that Table 1 lists, MailMessage and SmtpClient are the two core classes that you need to work with to send the simplest of mails.

Implementation

The SmtpClient class handles the actual sending of e-mail. For a simple mail, you can directly pass in the To address, from, subject, and body of the mail to one of the SmtpClient's overloaded send methods. However, this approach works only for simple mails that don't need any advanced formatting, which is normally provided by the MailMessage class.

To have complete control over the mail message, you need to create an instance of the MailMessage class and set its properties to appropriate values. For the purposes of this example, create a Visual C# Class Library project named MailServer using Visual Studio 2005. Once the project is created, rename the default class to MailService. To the MailService class, add a method named SendMail and modify its code to look as follows (an example of how to use the MailMessage class to create a mail message and then send it using the SmtpClient object):

public void SendMail(string from, string to,
                     string subject, string body)
{
   string mailServerName = "smtp.test.com";
   try
   {
      //MailMessage represents the e-mail being sent
      using (MailMessage message = new MailMessage(from,
             to, subject, body))
      {
         message.IsBodyHtml = true;
         SmtpClient mailClient = new SmtpClient();
         mailClient.Host = mailServerName;
         mailClient.UseDefaultCredentials = true;
         mailClient.DeliveryMethod =
            SmtpDeliveryMethod.PickupDirectoryFromIis;
         //Send delivers the message to the mail server
   mailClient.Send(message);
      }
   }
   catch (SmtpException ex)
   {
      throw new ApplicationException
         ("SmtpException has oCCured: " + ex.Message);
   }
   catch (Exception ex)
   {
      throw ex;
   }
}

In the above code, at the time of creating an instance of the MailMessage class, you pass in the From, To, Subject, and body of the message as arguments. Then, you set the IsBodyHtml property to true to indicate the type of mail you want to send. After that, you create an instance of the SmtpClient object and then set its properties, such as Host, UseDefaultCredentials, and DeliveryMethod, to appropriate values. Finally, you send the mail using the Send method, which sends out the mail in a synchronous manner. Note that at the time of sending a mail, if an SMTP exception occurs, it will be handled in the SmtpException catch block. All other exceptions are caught by the generic Exception block. Also note that in the above method, you directly set the To property of the MailMessage object to the supplied value. If you are sending mails to multiple recipients, you need to create that many instances of MailAddress objects and add them to the MailMessage.To property, which represents a collection of MailAddressCollection objects.

Now that you have created the SendMail method, it's time to call that method from a client application.

Send Mails from within a .NET 2.0 Application

Mail Client Implementation

To test the SendMail method, add a Visual C# Windows Forms application named MailClient to the existing solution and add a project reference to the MailServer using the Project->Add Reference dialog box. Once the reference is added, add a button control to the Form and double-click on the button control to bring up the Click event of the control in the code window. Modify the Click event of the button control to look as follows:

private void btnSendMail_Click(object sender, EventArgs e)
{
   MailService service = new MailService();
   string from = "thiruthangarathinam@yahoo.com";
   string to = "thiruthangarathinam@yahoo.com";
   string subject = "Sending Mails from .NET 2.0";
   string body = "This is the body of the message";
   service.SendMail(from, to, subject, body); ;
   MessageBox.Show("Mail sent");
}

As you can see, the implementation of the Click event is very simple and straightforward. You just create an instance of the MailService class and then simply call its SendMail method, passing in the required parameters. If everything is successful, you will get a message box indicating that the message has been sent successfully.

Including CC and BCC Addresses

In the above example, you sent the mail to all the addressees indicated in the To field of the MailMessage. You may want to have CC and BCC addressees for your mail as well. To accomplish this, you need to add the CC and BCC addresses to the MailAddress object and then add them to the MailAddressCollection object that is available through the CC and BCC properties of the MailMessage object. When the SendMail method is modified to support CC and BCC addresses, it looks as follows:

public void SendMail(string from, string to,
                     string CC, string BCC,
                     string subject, string body)
{
   string mailServerName = " smtp.test.com";
   try
   {
      //MailMessage represents the e-mail being sent
      using (MailMessage message = new MailMessage(from,
             to, subject, body))
      {
         if (CC != null)
         {
            if (CC.Trim().Length > 0)
            {
               MailAddress CCAddress = new
                  MailAddress(CC);
               message.CC.Add(CCAddress);
            }
         }
         if (BCC != null)
         {
            if (BCC.Trim().Length > 0)
            {
               MailAddress BCCAddress = new
                  MailAddress(BCC);
               message.BCC.Add(BCCAddress);
            }
         }
         message.IsBodyHtml = true;
         SmtpClient mailClient = new SmtpClient();
         mailClient.Host = mailServerName;
         mailClient.UseDefaultCredentials = true;
         mailClient.DeliveryMethod =
            SmtpDeliveryMethod.PickupDirectoryFromIis;
         //Send delivers the message to the mail server
   mailClient.Send(message);
      }
   }
   catch (SmtpException ex)
   {
      throw new ApplicationException
         ("SmtpException has oCCured: " + ex.Message);
   }
   catch (Exception ex)
   {
      throw ex;
   }
}

In the modified version of the SendMail method, the main difference is the addition of CC and BCC parameters. These parameters are added to the CC and BCC properties of the MailMessage object, respectively. The CC and BCC properties of the MailMessage object return an instance of the MailAddressCollection, to which you add individual MailAddress objects as follows:

         if (CC != null)
         {
            if (CC.Trim().Length > 0)
            {
               MailAddress CCAddress = new
                  MailAddress(CC);
               message.CC.Add(CCAddress);
            }
         }
         if (BCC != null)
         {
            if (BCC.Trim().Length > 0)
            {
               MailAddress BCCAddress = new
                  MailAddress(BCC);
               message.BCC.Add(BCCAddress);
            }
         }

If you are adding multiple recipients to the CC address, you need to create that many instances of the MailAddress objects and add them to the MailMessage.CC property. Note that the above example assumes there will be only one addressee listed in the CC address.

Sending Attachments

What you have seen so far are only basic functionalities of System.Net.Mail namespace. There is a lot more to the System.Net.Mail namespace. For example, by using the System.Net.Mail classes, you can send attachments as part of the mail messages. To accomplish this, you need to use the Attachment class, which provides a lot of flexibility in that you can load an attachment from a file or from a stream. Once you create an instance of the Attachment class, you then add it to the AttachmentCollection by calling the MailMessage.Attachments.Add method. The following code shows the code required:

Attachment attach = new Attachment(attachmentPath);
message.Attachments.Add(attach);

Now that you have sent the code required for adding attachments, modify your SendMail method to send attachments as follows:

public void SendMail(string from, string to,
   string subject, string body, string attachments)
{
   string mailServerName = "smtp.test.com";
   try
   {
      //MailMessage represents the e-mail being sent
      using (MailMessage message = new MailMessage(from,
         to, subject, body))
      {
         message.IsBodyHtml = true;
         SmtpClient mailClient = new SmtpClient();
         mailClient.Host = mailServerName;
         mailClient.UseDefaultCredentials = true;
         mailClient.DeliveryMethod =
            SmtpDeliveryMethod.PickupDirectoryFromIis;
         if (attachments != null)
         {
            attachments = attachments.Trim();
            if (attachments.Length != 0)
            {
               //Get the list of semi-colon separated
               //attachments into an array
              string[] arr = attachments.Split(';');
              foreach (string str in arr)
              {
                 Attachment attach = new Attachment(str);
                 message.Attachments.Add(attach);
              }
            }
         }

         //Send delivers the message to the mail server
   mailClient.Send(message);
      }
   }
   catch (SmtpException ex)
   {
      throw new ApplicationException
         ("SmtpException has oCCured: " + ex.Message);
   }
   catch (Exception ex)
   {
      throw ex;
   }
}

In the above code, the attachments are sent in the form of semicolon-separated values in a single string value to the SendMail method. Then, you split the attachments into an array, loop through the array, and add all the attachments to the MailMessage.Attachments.Add method as follows:

         if (attachments != null)
         {
            attachments = attachments.Trim();
            if (attachments.Length != 0)
            {
               //Get the list of semi-colon separated
               //attachments into an array
              string[] arr = attachments.Split(';');
              foreach (string str in arr)
              {
                 Attachment attach = new Attachment(str);
                 message.Attachments.Add(attach);
              }
            }
         }

Once you add the attachments to the AttachmentCollection, the attachment will be embedded automatically in the mail when it is sent. That's all there is to sending attachments as part of the mail.

Asynchronous Approach to Sending Mail

Sometimes, you may want to send mail asynchronously. For example, if you are sending a lot of mail through your application, the synchronous approach might not work. In such a scenario, you can use SendAsync. Before using the SendAsync method, you need to set up the SendCompletedCallback event handler. The following code shows the implementation required:

mailClient.SendCompleted +=
   new SendCompletedEventHandler(SendCompletedHandler);
mailClient.SendAsync(message, null);

The SendCompletedHandler is declared as follows:

void SendCompletedHandler(System.Object sender, 
   AsyncCompletedEventArgs e)
{
   //Code to process the completion
}

The AsyncCompletedEventArgs object supplied to the SendCompletedEventHandler delegate exposes a property named Error that will allow you to check whether an error has occurred during an asynchronous operation. The Error property returns an object of type Exception that you can examine to determine the exact cause of the error condition.

Generating the Contents of the Mail

Generally, when you send HTML-based e-mails, you can generate the body of the mail in different ways. For example, you can directly hardcode the body of the mail in the class that sends out the mail. The problem with this approach is that whenever you need to change the format of the mail, you need to change the code in the component, recompile it, and redeploy it on the server. This makes maintaining the component a nightmare. Fortunately, you can use XML in conjunction with XSL to solve this problem. In this approach, you can dynamically generate the data required for the mail in XML format and then apply an external XSL style sheet to transform the XML data into HTML. By using the following helper function, you can generate the body of the mail in the form of a string, which then can be used to set the Body property of the MailMessage object:

public string GenerateMailBody(string inputXml, string xslPath)
{
   XmlDocument xmlDoc = new XmlDocument();
   xmlDoc.LoadXml(inputXml);
   XslCompiledTransform transform = new
      XslCompiledTransform();
   //Load the XSL stylsheet into XslCompiledTransform
   transform.Load(xslPath);
   StringWriter writer = new StringWriter();
   //Transform the xml contents into HTML by applying XSL
   transform.Transform(xmlDoc,null, writer);
   string bodyOfMail = writer.ToString();
   return bodyOfMail;
}

The GenerateMailBody function takes in the input XML string and loads it into an XmlDocument object. Then, it creates an instance of the new XslCompiledTransform object (which is one of the new classes in the .NET Framework 2.0 used for XSL transformations). After that, you invoke the Transform method of the XslCompiledTransform object to transform the XML into HTML. To the Transform method, you also supply the StringWriter object as an argument so that the output of the transformation can be captured in that object. Then, you simply return the string value of the StringWriter object back to the caller. By simply reusing the above helper method, you can generate the right body of the HTML mail based on the input XML data and XSL stylesheet.

Mail Processing Facelift

The .NET Framework 2.0 provides improvements in almost all areas, and mail processing is one of them. In this article, you have seen how to send mail by using the new features of .NET Framework 2.0. You also learned how to send attachments by using the Attachment class. Then, you studied the use of XML and XSL in generating the body of a mail. Although the examples were simple in functionality, they should provide a solid foundation for understanding the use of new mail-processing features in .NET Framework 2.0.



Downloads

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Today's agile organizations pose operations teams with a tremendous challenge: to deploy new releases to production immediately after development and testing is completed. To ensure that applications are deployed successfully, an automatic and transparent process is required. We refer to this process as Zero Touch Deployment™. This white paper reviews two approaches to Zero Touch Deployment--a script-based solution and a release automation platform. The article discusses how each can solve the key …

  • On-demand Event Event Date: December 18, 2014 The Internet of Things (IoT) incorporates physical devices into business processes using predictive analytics. While it relies heavily on existing Internet technologies, it differs by including physical devices, specialized protocols, physical analytics, and a unique partner network. To capture the real business value of IoT, the industry must move beyond customized projects to general patterns and platforms. Check out this webcast and join industry experts as …

Most Popular Programming Stories

More for Developers

RSS Feeds