SEO Werkt!

Seo werkt!

ASP.NET – Sending Email Both in HTML and Plain Text

without comments

In this article you will learn how to send email using ASP.NET. Yes, there are plenty of other articles that cover sending email via .NET, but after spending a day doing research, I was amazed at how many articles failed to provide either a correct solution or a real world example. I found that many articles suggest you create your HTML email by using a string with the HTML markup in it. That’s crazy and not at all a real world solution, at least not for most situations. In this article we will look at a more realistic solution. One in which we use a regular HTML file as our template for the email. The template file will be a standard HTML file with the exception of some placeholders that we will use to populate our content and images right before we send the email. Think mail-merge in Microsoft Word. Finally, we will also learn how to send the email in such a way that if the email recipient’s mail-client can’t render HTML they will get an alternate plain text version.

Let’s start by looking at the code in its entirety; the people that just want to grab the code and use it can do so. I will then explain the code.

C#:

  1. // CREATE EMAIL
  2. // first we create a plain text version and set it to the AlternateView
  3. // then we create the HTML version
  4. MailMessage msg = new MailMessage();
  5.  
  6. msg.From = new MailAddress(TextBoxYourEmail.Text);
  7. msg.Subject = “Event: “ + labelEventName.Text;
  8. msg.To.Add(TextBoxEmail1.Text);
  9.  
  10. // create a string to hold all email addresses
  11. StringBuilder sbEmailTo = new StringBuilder();
  12. sbEmailTo.Append(TextBoxEmail1.Text);
  13.  
  14. if (!String.IsNullOrEmpty(TextBoxEmail2.Text)) { msg.To.Add(TextBoxEmail2.Text); sbEmailTo.Append(“, “ + TextBoxEmail2.Text); }
  15. if (!String.IsNullOrEmpty(TextBoxEmail3.Text)) { msg.To.Add(TextBoxEmail3.Text); sbEmailTo.Append(“, “ + TextBoxEmail3.Text); }
  16. if (!String.IsNullOrEmpty(TextBoxEmail4.Text)) { msg.To.Add(TextBoxEmail4.Text); sbEmailTo.Append(“, “ + TextBoxEmail4.Text); }
  17. if (!String.IsNullOrEmpty(TextBoxEmail5.Text)) { msg.To.Add(TextBoxEmail5.Text); sbEmailTo.Append(“, “ + TextBoxEmail5.Text); }
  18.  
  19. String plainEmail = TextBoxYourName.Text + ” has invited you to an event! \r\n \r\n +
  20.     “Event Name: “ + labelEventName.Text + \n +
  21.     “Event Date: “ + eventTextBox.Text + \n +
  22.     “Event Description: “ + labelEventDescription.Text + \r\n \r\n +
  23.     “Message: “ + TextBoxPersonalMessage.Text;
  24.  
  25. //first we create the Plain Text part
  26. AlternateView plainView = AlternateView.CreateAlternateViewFromString(plainEmail, null, “text/plain”);
  27. msg.AlternateViews.Add(plainView);
  28.  
  29. //now create the HTML version
  30. MailDefinition message = new MailDefinition();
  31. message.BodyFileName = “email.htm”;
  32. message.IsBodyHtml = true;
  33. message.From = TextBoxYourEmail.Text;
  34. message.Subject = “Zoo Event: “ + labelEventName.Text;
  35.  
  36. //embed images for the email
  37. EmbeddedMailObject emo = new EmbeddedMailObject();
  38. emo.Path = @”~\Images\email\hdr_roar.gif”;
  39. emo.Name = “hdr”;
  40.  
  41. EmbeddedMailObject emo2 = new EmbeddedMailObject();
  42. emo2.Path = @”~\Images\email\box_top.gif”;
  43. emo2.Name = “box_top”;
  44.  
  45. message.EmbeddedObjects.Add(emo);
  46. message.EmbeddedObjects.Add(emo2);
  47.  
  48. //Build replacement collection to replace fields in email.htm file
  49. ListDictionary replacements = new ListDictionary();
  50. replacements.Add(“<%EVENTDATE%>”, eventTextBox.Text);
  51. replacements.Add(“<%EVENTNAME%>”, labelEventName.Text);
  52. replacements.Add(“<%FROMNAME%>”, TextBoxYourName.Text);
  53. replacements.Add(“<%EVENTDESCRIPTION%>”, labelEventDescription.Text);
  54. replacements.Add(“<%PERSONALMESSAGE%>”, TextBoxPersonalMessage.Text);
  55.  
  56. //now create mail message using the mail definition object
  57. //the CreateMailMessage object takes a source control object as the last parameter,
  58. //if the object you are working with is webcontrol then you can just pass "this",
  59. //otherwise create a dummy control as below.
  60. MailMessage msgHtml = message.CreateMailMessage(sbEmailTo.ToString(), replacements, new LiteralControl());
  61.  
  62. AlternateView htmlView = AlternateView.CreateAlternateViewFromString(msgHtml.Body, null, “text/html”);
  63. msg.AlternateViews.Add(htmlView);
  64.  
  65. // send email now (check web.config)
  66. SmtpClient smtp = new SmtpClient();
  67. smtp.Send(msg);

The Setup

Add the System.Net.Mail namespace. The System.Net.Mail namespace contains everything we need to send email using a Simple Mail Transfer Protocol (SMTP) server for delivery.

Modify the Web.config file to include the below:

CODE:

  1. <system.net>
  2.     <mailSettings>
  3.       <smtp from=“admin@company.com”>
  4.         <network host=“localhost” port=“25″  />
  5.       </smtp>
  6.     </mailSettings>
  7.   </system.net>

The kicker and not well documented part to note is the from=”admin@company.com” in the smtp tag. You can change the from address later, but the MailDefinition class needs this here.

That’s it for setup. Now let’s look at the first chunk of code.

Create The Plain Text Version

C#:

  1. MailMessage msg = new MailMessage();

The MailMessage class represents an email message that can be sent using the SmtpClient class.

C#:

  1. msg.From = new MailAddress(TextBoxYourEmail.Text);
  2. msg.Subject = “Event: “ + labelEventName.Text;
  3. msg.To.Add(TextBoxEmail1.Text);

Pretty straight-forward. This just assigns the From, Subject and To properties to our mail message.

C#:

  1. // create a string to hold all email addresses
  2. StringBuilder sbEmailTo = new StringBuilder();
  3. sbEmailTo.Append(TextBoxEmail1.Text);
  4.  
  5. if (!String.IsNullOrEmpty(TextBoxEmail2.Text)) { msg.To.Add(TextBoxEmail2.Text); sbEmailTo.Append(“, “ + TextBoxEmail2.Text); }
  6. if (!String.IsNullOrEmpty(TextBoxEmail3.Text)) { msg.To.Add(TextBoxEmail3.Text); sbEmailTo.Append(“, “ + TextBoxEmail3.Text); }
  7. if (!String.IsNullOrEmpty(TextBoxEmail4.Text)) { msg.To.Add(TextBoxEmail4.Text); sbEmailTo.Append(“, “ + TextBoxEmail4.Text); }
  8. if (!String.IsNullOrEmpty(TextBoxEmail5.Text)) { msg.To.Add(TextBoxEmail5.Text); sbEmailTo.Append(“, “ + TextBoxEmail5.Text); }

In this example they have the option of sending the email to more than one recipient. So we perform a check on the four optional text-boxes to see if they have email addresses and if they are not empty then we add them to our MailMessage instance. In addition, we append them to our StringBuilder instance which we will end up using later.

C#:

  1. String plainEmail = TextBoxYourName.Text + ” has invited you to an event! \r\n \r\n +
  2.     “Event Name: “ + labelEventName.Text + \n +
  3.     “Event Date: “ + eventTextBox.Text + \n +
  4.     “Event Description: “ + labelEventDescription.Text + \r\n \r\n +
  5.     “Message: “ + TextBoxPersonalMessage.Text;
  6.  
  7. //first we create the Plain Text part
  8. AlternateView plainView = AlternateView.CreateAlternateViewFromString(plainEmail, null, “text/plain”);
  9. msg.AlternateViews.Add(plainView);

Here we simply create a string which we’ll use as our plain-text email message. But remember, we only want to use the plain-text version of the email if their mail client does not support HTML. Therefore we use the AlternateView class and add it to our MailMessage instance. We could have chosen not to use the alternate view and just made it the body of our MailMessage instance, but not this time.

That’s it for the plain-text version, now we will handle the HTML version.

Create The HTML Version

C#:

  1. //now create the HTML version
  2. MailDefinition message = new MailDefinition();
  3. message.BodyFileName = “email.htm”;
  4. message.IsBodyHtml = true;
  5. message.From = TextBoxYourEmail.Text;
  6. message.Subject = “Zoo Event: “ + labelEventName.Text;

Notice we use the MailDefinition class this time and not the MailMessage class as we did with the plain-text version. That’s because it’s the MailDefinition class that allows us to to create an email from an HTML file. Notice the BodyFileName property that we have set to our “email.htm” file. This is just a regular old HTML file. Lastly, we set the IsBodyHtml property to true.

C#:

  1. //embed images for the email
  2. EmbeddedMailObject emo = new EmbeddedMailObject();
  3. emo.Path = @”~\Images\email\hdr_roar.gif”;
  4. emo.Name = “hdr”;
  5.  
  6. EmbeddedMailObject emo2 = new EmbeddedMailObject();
  7. emo2.Path = @”~\Images\email\box_top.gif”;
  8. emo2.Name = “box_top”;
  9.  
  10. message.EmbeddedObjects.Add(emo);
  11. message.EmbeddedObjects.Add(emo2);

The above code adds two images to the HTML file. The EmbeddedMailObject represents an item to embed in a mail message. Notice the Name property. This is important because in our HTML file (email.htm) we have this <img src=”cid:hdr” alt=”" /> code which is where it maps to the image. This way of adding images to our MailDefinition object will send the images with the email. If you don’t wish to send images with your email you may choose to simply add absolute paths to your images in your HTML file like normal. Just make sure the paths are absolute.

C#:

  1. //Build replacement collection to replace fields in email.htm file
  2. ListDictionary replacements = new ListDictionary();
  3. replacements.Add(“<%EVENTDATE%>”, eventTextBox.Text);
  4. replacements.Add(“<%EVENTNAME%>”, labelEventName.Text);
  5. replacements.Add(“<%FROMNAME%>”, TextBoxYourName.Text);
  6. replacements.Add(“<%EVENTDESCRIPTION%>”, labelEventDescription.Text);
  7. replacements.Add(“<%PERSONALMESSAGE%>”, TextBoxPersonalMessage.Text);

This is an important part. This is where we pass in fields to our HTML template. Within our HTML file we find this <%EVENTDATE%> . This is a placeholder that we use to pass in content. Pretty cool eh? Almost like a mail-merge in Word. So all the above gets mapped into our HTML template. Now we see the power of this solution. It sure beats creating a huge string. We have a regular old HTML file with the placeholders that we pass in the content. Any future changes can be done right in the HTML file. Nice…

Now the last code section:

C#:

  1. //now create mail message using the mail definition object
  2. //the CreateMailMessage object takes a source control object as the last parameter,
  3. //if the object you are working with is webcontrol then you can just pass "this",
  4. //otherwise create a dummy control as below.
  5. MailMessage msgHtml = message.CreateMailMessage(sbEmailTo.ToString(), replacements, new LiteralControl());
  6.  
  7. AlternateView htmlView = AlternateView.CreateAlternateViewFromString(msgHtml.Body, null, “text/html”);
  8. msg.AlternateViews.Add(htmlView);
  9.  
  10. // send email now (check web.config)
  11. SmtpClient smtp = new SmtpClient();
  12. smtp.Send(msg);

The CreateMailMessage method creates the email message and does the merging of our replacement list with the placeholders. We also pass in the string that we created earlier. Remember the string held all the email recipient addresses. The last parameter is looking for a control that owns the MailDefinition. We don’t have one so we just pass in a dummy control.

All that remains is to send the email message via the smtp protocol. If everything in your Web.config file is set up correctly your email should be on the way.

Written by Golgotha

February 5th, 2009 at 3:36 pm