Creating HTML emails using VB 9 and LINQ by ThinqLinq

Creating HTML emails using VB 9 and LINQ

Today, I'm not looking at sending mass spam using LINQ to pull a list of recipients. I'm actually referring to the ability to generate the message body using XML Literals. Using the System.Net.Mail.MailMessage object, we can easily send emails to an SMTP server.

The body of the email can either be plain text or HTML. Dynamically generating the text is often a laborious task involving a string builder and lots of method calls. The body corresponds to the body portion of a HTML page. If you use well formed XHTML in the body, you are actually generating a specialized version of XML. Once we are working with XML, we can use XML Literals in VB to format our output.

I recently had to do this on a project to send lists of updated values from an external source. In the body, I needed to dynamically fill a HTML table with the new values. The table consists of 4 columns: State, County, Limit, Effective Date. I begin by laying out the content in a HTML editor (like Visual Studio 2008...) Here's the results:

<body>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur eros purus, suscipit ac, pulvinar vel, aliquet vehicula, pede. Duis eros dolor, iaculis non, aliquam sed, tincidunt ac, diam.
   
<table>
     
<tr><th>State</th>
           
<th>County</th>
           
<th>New Limit</th>
           
<th>Effective Date</th>
     
</tr><tr><td>XX</td>
                     
<td>Foo</td>
                    
<td>$123</td>
                     
<td>1/1/2000</td>
               
</tr>
   
</table>
 
</body>

I know what you must be thinking by now: Gee Jim, how could you come up with such a beautiful page. As Bones would say, "D@mmit Jim, I'm programmer not a designer." We'll keep it clean for now to focus on what is yet to come.

Realize that our body tag is actually the root of a well-formed XML document. As such, we can copy it as a template directly into our tool (which is a console application by the way), add a reference to System.Linq and System.Xml.Linq, and paste it into our VB module assigning a variable, let's call it "body" to the XML.

While we're at it, we'll go ahead and insert new rows into the table based on the results of an object query. In this query, we'll iterate over the records we are adding which is an IEnumerable(Of Limit). We'll project a new row (<tr>) for each object in our iteration. Rather than imperatively iterating, we'll use LINQ's declarative syntax In addition, we'll insert our values using the <%= %> place holders. Here's the resulting declaration:

Friend Shared Sub SendUpdate(ByVal newItems As IEnumerable(Of FhaLimit))
Dim body = _
  <body>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur eros purus, suscipit ac, pulvinar vel, aliquet vehicula, pede. Duis eros dolor, iaculis non, aliquam sed, tincidunt ac, diam. 
    <table>
     
<tr><th>State</th>
           
<th>County</th>
           
<th>New Limit</th>
           
<th>Effective Date</th>
     
</tr><%= From limit In newItems _
                      Order By limit.State, limit.CountyName _
                      Select <tr><td><%= limit.State %></td>
                                      
<td><%= limit.CountyName %></td>
                                      
<td><%= limit.Units1.Value.ToString("c0") %></td>
                                      
<td><%= limit.LimitTransactionDate.ToShortDateString %></td>
                               
</tr> %>
   
</table>
 
</body>

If you've coded ASP.NET, the resulting declaration should look very familiar. Realize that this is being done in a VB module in a console application. We are not coding in a .ASPX file! The resulting maintainability of this code is much better than the old way using string builders or XSLT.

To finish off the task, we are going to send the message with our new XHTML body. This is very easy with .NET as well.

Dim message As New System.Net.Mail.MailMessage("from@ThinqLinq.com", "to@ThinqLinq.com", "Limits Updated", body.ToString)
message.IsBodyHtml = True
Dim server As New System.Net.Mail.SmtpClient(My.Settings.SmtpServer)
server.Send(message)

There you go, a quick and painless way to create HTML emails using VB 9 and LINQ. Let me know what you Thinq.

Posted on - Comment
Categories: LINQ) - VB) - VB Dev Center) - Linq to XML) -
comments powered by Disqus