5

I have a C#/.NET app which currently uses StringBuilder to generate an HTML email message.

A new message format has been developed and now includes more formatting and CSS. I'd like to avoid appending each line of the file using StringBuilder, so I thought it best to include the HTML file as a resource.

However, there are about 21 variables within the CSS and HTML which I need to change on the fly. My first thought was to replace them with the standard String.Format placeholders ({0}, {1} etc) but when viewing the HTML, validation complains about these.

I'm rather stumped as to what the best practice is for storing a 200-line HTML file and changing parts of it before inclusion in an email.

Example:

Within the CSS, I need to change the color of certain elements, like this:

#header
{
    background-color: {0};
}

And within the HTML, I need to change strings and URLs, like this:

<img src="{1}" />
<span>{2}</span>

It seems including the HTML as a resource in the project would be best, but trying to use String.Format with that resource, regardless if it would work, is a poor method because of the aforementioned validation errors.

Any suggestions?

JYelton
  • 35,664
  • 27
  • 132
  • 191
  • 1
    why is it a problem that validation fails on the "template HTML" before the placeholders are replaced ? IMHO the only important point is the it validates correctly AFTER replacing the placeholders with some content! – Yahia May 18 '12 at 17:13
  • Then you'd have to remember which means what. And you need maintain argument count consistent. Use replaceable tokens like <%token_name%> and create simple find-replace method to replace tokens from some dictionary. – Val Bakhtin May 18 '12 at 17:13
  • This question is like a rose in a Stack Overflow full of weeds. I hope it gets an answer. – Kendall Frey May 18 '12 at 17:20

6 Answers6

5

I think you can try t4 tamplate

With t4 template you can even do more complex things like

<table>
<# for (int i = 1; i <= 10; i++)
   { #>
     <tr><td>Test name <#= i #> </td>
         <td>Test value <#= i * i #> </td> </tr>
 <# } #>
</table>
Asif Mushtaq
  • 13,010
  • 3
  • 33
  • 42
3

You can use the Razor engine to render a HTML string:

<h2>Items:</h2>
@foreach(var item in list)
{
    <p>Item: @item.Description</p>
}

These answers Is it possible to use Razor View Engine outside asp.net give some nice links to do so.

Community
  • 1
  • 1
Lucas Reis
  • 743
  • 11
  • 21
2

Instead of using {1} use a name e.g. Table1HeaderImage, then instead of using String.Format use String.Replace. You could have a collection of thingies to put in thehtml then, a quick loop, even extra attributes for customisation from users version, etc.

Tony Hopkinson
  • 20,172
  • 3
  • 31
  • 39
2

You could create a preprocessed T4 text template file. http://msdn.microsoft.com/en-us/library/ee844259 One of the nice features T4 text templates is that they can be used to auto generate any kind of text file.

BenCamps
  • 1,694
  • 15
  • 25
0

What I do is something like this:

StreamReader reader = new StreamReader(Server.MapPath("Email/email.html"));
string email_html = reader.ReadToEnd();
reader.Close();

email_html = email_html.Replace("[link]", activation_link);
vpascoal
  • 278
  • 2
  • 4
  • 15
0

I would use <%0%>, <%1%>, etc. instead of {0}, {1}, etc.

At runtime, you would:

  1. Replace all { with {{ and } with }}
  2. Replace all <% with { and %> with }
  3. String.Format()

You could also do as Val Bakhtin suggested, and use names instead of numbers. Then the process would be simply:

  1. Replace all <%name%> with dictionary["name"]
Kendall Frey
  • 43,130
  • 20
  • 110
  • 148