Send Mails from within a .NET 2.0 Application (2)

原创 2006年05月23日 00:17:00

http://www.developer.com/net/net/print.php/11087_3511731_2


By
Thiru Thangarathinam
June 10, 2005

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.

 

为什么必须是final的呢?

一个谜团 如果你用过类似guava这种“伪函数式编程”风格的library的话,那下面这种风格的代码对你来说应该不陌生: 1 2 3 4 5 6 7 8 9 ...
  • cuipengfei1
  • cuipengfei1
  • 2013年06月23日 00:57
  • 8254

基于MFC的ActiveX控件的退出(卸载)

一直以来,写了控件后用起来很正常,最近,客户要把这控件用在web页面上,那么问题它就来了。大多数时候的运行环境: os: win7、win10 浏览器:ie8、ie11,这里不考虑ie之外的其它浏...
  • jszj
  • jszj
  • 2017年01月12日 17:58
  • 923

TensorFlow 研究实践 一

一、Caffe、TensorFlow、MXnet三个开源库对比 http://www.kuqin.com/shuoit/20151124/349098.html 选择学习TensorFlow二、深...
  • forest_world
  • forest_world
  • 2016年05月03日 17:41
  • 14444

Oracle函数 --聚合函数中的语法within group

Oracle的聚合函数一般与group by 联合使用,但一般通过group by 聚合 但某些聚合函数会后跟 WITHIN GROUP (ORDER BY expr [ DESC ...
  • richieruan
  • richieruan
  • 2017年01月10日 16:08
  • 3432

Storm安装介绍

将安装过storm 0.9.1的过程流水记录,稍微整理了一下,以备日后查看。 0. introduction 配置项说明: storm在conf/storm.yaml包含了一些配置信息。 ...
  • jollypigclub
  • jollypigclub
  • 2015年07月14日 09:38
  • 2052

自定义ProgressDialog,方便集成,适合新手,附源码

为什么写这个博客。。因为有个项目用到ProgressDialog,原生的太丑了。维护起来太麻烦,本想在网上随便下载一下用一下;可是竟然要我5积分,囊中羞涩,随意自己来吧,本来也挺简单的。 首先先布局...
  • u011449334
  • u011449334
  • 2018年01月12日 18:28
  • 27

Asp.net Core中SignalR Core预览版的一些新特性前瞻,附源码(消息订阅与发送二进制数据)

前言 一晃一个月又过去了,上个月有个比较大的项目要验收上线.所以忙的脚不沾地.现在终于可以忙里偷闲,写一篇关于SignalR Core的文章了. 先介绍一下SignalR吧,如下: ASP.NE...
  • sD7O95O
  • sD7O95O
  • 2017年12月08日 00:00
  • 159

Oracle11.2新特性之listagg函数

Oracle11.2新增了LISTAGG函数,可以用于字符串聚集,测试如下: 1,版本 SQL> select * from v$version; BANNER -----------...
  • lively1982
  • lively1982
  • 2013年02月27日 22:04
  • 14290

ADO.NET 2.0中的异步命令执行

http://www.cnblogs.com/haowenbiao/archive/2008/05/11/1192768.html 在ADO.NET 2.0版本中,我们不仅希望使现有的方案更为简...
  • mituan1234567
  • mituan1234567
  • 2014年03月05日 15:41
  • 573

asp.net web api 2.0 实现跨域资源共享

asp.net web api 2 对跨域资源共享的支持1. 同源策略:同源策略是浏览器为保证安全最基本的功能, 只有同源的脚本才能够被执行,那么什么是同源呢?同源是指协议,域名以及端口号都相同,任何...
  • zhanxueguang
  • zhanxueguang
  • 2015年07月09日 20:47
  • 1352
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Send Mails from within a .NET 2.0 Application (2)
举报原因:
原因补充:

(最多只允许输入30个字)