November 24, 2014
Hot Topics:

Send Mails from within a .NET 2.0 Application

  • June 10, 2005
  • By Thiru Thangarathinam
  • Send Email »
  • More Articles »

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.

Download the Accompanying Code

Click here to download the code that accompanies this article.

About the Author

Thiru Thangarathinam has six years of experience in architecting, designing, developing, and implementing applications using object-oriented application development methodologies. He also possesses a thorough understanding of the software life cycle (design, development, and testing). He holds several certifications, including MCAD for .NET, MCSD, and MCP. Thiru is an expert with ASP.NET, .NET Framework, Visual C# .NET, Visual Basic .NET, ADO.NET, XML Web services, and .NET Remoting. Thiru also has authored numerous books and articles. Contact him at thiruthangarathinam@yahoo.com.





Page 2 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Rocket Fuel