1

I need to provide a variable bit of data (the "body" of an email) to a (string) member of a list of string, and am trying to build it using string.format, but I get, ") expected" on the "http" part here:

string htmlBodyAmalgamation = string.Format(@"<html><body><img src=\"http://www.platypus.com/wp-
content/themes/platypus/images/pa_logo_notag.png\" alt=\"Platypus logo\" width=\"199\" height=\"130\" ><p>{0}</p>", body);

I get that err msg whether I have 0, 1, 2, or 3 backwhacks ("\") prepended to the "http".

If there is no variable portion (if the body is static/known in advance) I can do this:

List<String> htmlBody = new List<string>
    {
        "<html><body><img src=\"http://www.platypus.com/wp-content/themes/platypus/images/pa_logo_notag.png\" alt=\"Platypus logo\" width=\"199\" height=\"130\" ><p>Your Platypus Price Push report is attached.</p>",
        "</body></html>"
    };
mailItem.HTMLBody = string.Join(Environment.NewLine, htmlBody.ToArray());

...and it works fine.

So it's trying to embed the variable "body" value via string.format as follows that is proving problematic:

string htmlBodyAmalgamation = string.Format(@"<html><body><img src=\"http://www.platypus.com/wp-content/themes/platypus/images/pa_logo_notag.png\" alt=\"Platypus logo\" width=\"199\" height=\"130\" ><p>Your Platypus Price Push report is attached.</p>", body);
List<String> htmlBody = new List<string>
    {
        htmlBodyAmalgamation,
        "</body></html>"
    };

What's the trick to get the html and string.format to work together?

B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862

2 Answers2

1

Thought I'd share an elegant solution that I used a year or so ago. We used HTML templates for e-mails as well and, found that the Razor engine is actually (obviously) quite good at doing that.

Our code was the following:

    public string CompileMessage(string templateHtml, object modelClass)
    {
        try
        {
            TemplateServiceConfiguration templateConfig = new TemplateServiceConfiguration
            {
                Resolver = new TemplateResolver(),
                Language = Language.CSharp,
                Debug = true,
            };

            Razor.SetTemplateService(new TemplateService(templateConfig));

            return Razor.Parse(templateHtml, modelCLass);
        }
        catch (Exception ex)
        {
            Logger.Log4Net.Error("Failed to compile email template using Razor", ex);
            return "Error occurred (" + ex.Message + "). Check the logfile in the vicinity of " + DateTime.Now.ToLongTimeString() + ".";
        }
    }

Benefits:

  • Using Razor gave us the typesafety of giving a model with the "placeholders"
  • We had covered XSS and similar attacks as Razor always escapes values unless @Html.Raw() was used
  • It enabled business users to edit templates relatively safe without worrying about non-html compliant characters
  • Razor would take care of culture/ui culture in formatting strings
Gigabyte
  • 571
  • 6
  • 14
1

Seems simple enough - use single quotes instead of double, and omit the backwhacks:

string htmlBodyAmalgamation = string.Format(@"<html><body><img src='http://www.platypus.com/wp-content/themes/platypus/images/pa_logo_notag.png' alt='Platypus logo' width='199' height='130' ><p>{0}</p>", body);

Simpler yet, I can cut out some of the middlemen and just do this:

mailItem.HTMLBody = string.Format(@"<html><body><img src='http://www.platypus.com/wp-content/themes/platypus/images/pa_logo_notag.png' alt='Platypus logo' width='199' height='130' ><p>{0}</p></body></html>", body);
B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862
  • 1
    For a simple html contents using string format is completely OK, however for complicated scenarios like email templates consider using [run-time T4 templates](http://stackoverflow.com/a/39713817/3110834). – Reza Aghaei Jan 19 '17 at 00:13