tags:

views:

4745

answers:

9

Is there a better way to generate HTML email in C# (for sending via System.Net.Mail), than using a Stringbuilder to do the following:

string userName = "John Doe";
StringBuilder mailBody = new StringBuilder();
mailBody.AppendFormat("<h1>Heading Here</h1>");
mailBody.AppendFormat("Dear {0}," userName);
mailBody.AppendFormat("<br />");
mailBody.AppendFormat("<p>First part of the email body goes here</p>");

and so on, and so forth?

+1  A: 

Emitting handbuilt html like this is probably the best way so long as the markup isn't too complicated. The stringbuilder only starts to pay you back in terms of efficiency after about three concatenations, so for really simple stuff string + string will do.

Other than that you can start to use the html controls (System.Web.UI.HtmlControls) and render them, that way you can sometimes inherit them and make your own clasess for complex conditional layout.

Mark Dickinson
+1  A: 

Use the System.Web.UI.HtmlTextWriter class.

StringWriter writer = new StringWriter();
HtmlTextWriter html = new HtmlTextWriter(writer);

html.RenderBeginTag(HtmlTextWriterTag.H1);
html.WriteEncodedText("Heading Here");
html.RenderEndTag();
html.WriteEncodedText(String.Format("Dear {0}", userName));
html.WriteBreak();
html.RenderBeginTag(HtmlTextWriterTag.P);
html.WriteEncodedText("First part of the email body goes here");
html.RenderEndTag();
html.Flush();

string htmlString = writer.ToString();

For extensive HTML that includes the creation of style attributes HtmlTextWriter is probably the best way to go. However it can be a bit clunky to use and some developers like the markup itself to be easily read but perversly HtmlTextWriter's choices with regard indentation is a bit wierd.

In this example you can also use XmlTextWriter quite effectively:-

writer = new StringWriter();
XmlTextWriter xml = new XmlTextWriter(writer);
xml.Formatting = Formatting.Indented;
xml.WriteElementString("h1", "Heading Here");
xml.WriteString(String.Format("Dear {0}", userName));
xml.WriteStartElement("br");
xml.WriteEndElement();
xml.WriteElementString("p", "First part of the email body goes here");
xml.Flush();
AnthonyWJones
+10  A: 

You can use the MailDefinition class.

UPDATE - the previous link was broken
I've written a blog post on how to generate HTML e-mail body in C# using templates using the MailDefinition class.

MartinHN
Dang! I had no idea about this class! +1
Cerebrus
Awesome. +1 for education :)
Eoin Campbell
I didn't even knowm this existed, sheer genius it is... +1 and Accepted
Rob
+1. Nice, although limited, probably covers many uses. Not so useful if you want to programmatically include sections of HTML and/or loop through a set of items that need rendering.
AnthonyWJones
I became aware of it just recently. It is cool. I guess it tells you how important it is to look at the MSDN Documentation before writing a class for any problem yourself.I had written my own class, that did almost the same as MailDefinition. Too bad for me. Waste of time.
MartinHN
+1  A: 

I would recomend using templates of some sort. There are various different ways to approach this but essentially hold a template of the Email some where (on disk, in a database etc) and simply insert the key data (IE: Recipients name etc) into the template.

This is far more flexible because it means you can alter the template as required without having to alter your code. In my experience your likely to get requests for changes to the templates from end users. If you want to go the whole hog you could include a template editor.

Leather
A: 

Well, it really depends on the solution as I see it. I have done everything from grabbing user-input and formatting it automaticly from different patters. The best solution I've done with html mails was actually xml+xslt formatting since we knew the input of the mail up-front.

cyberzed
A: 

That depends how complex your requirements are. I once had an application that rendered a table in an HTML email and I used an ASP.NET Gridview to render the HTML- concatenating strings to generate a table would of been messy.

RichardOD
A: 

cyberzed - I have used a similar approach in the past (XML + XSLT) with good results too. This offers a lot of flexibility and means you code doesn't have to concern itself with the exact data this Email requires (Produce an XML doc containing all pertinent info and let the XSLT pick out the bit's it wants.

The only thing I would say is I found XSLT a bit of a headache to get into but I was fine once I got past the initial oddness.

Leather
A: 

I think it depends on you and what you send. If your information is seriously dynamic, then you will have a complex (figuratively speaking) time building the html in code. If it is not conplex, you could have most of it prebuilt and use the string.format method as posted earlier. I also found this static class for sending HTML emails on easykb.com

A: 

You might want to have a look at some of the template frameworks that are available at the moment. Some of them are spin offs as a result of MVC but that isn't required. Spark is a good one.

Simon Farrow