Lurgle.Alerting v1.2.2 released - Send results, plain text and HTML improvements

Table of Contents

Lurgle Update Time!

I've released an update to Lurgle.Alerting, the premier Lurgle Alerting library for Lurgling your Alerts!

This release is about updating some of the older code that was brought into the library:

  1. The Send, SendAsync, SendTemplate, SendTemplateAsync, SendTemplateFile, and SendTemplateFileAsync methods returned just a bool for success or failure.
  2. Improvements could be made to how we handle HTML and plain text in emails

Why didn't my Lurgle go?

FluentEmail largely suppresses exceptions when there are send failures. Lurgle was simply returning the FluentEmail.Core.Models.SendResponse.Successful bool .. which is ok if your email sent. 

If you wanted to "do" something when Successful == false, though, you were out of luck. Hence I've adjusted Lurgle.Alerting to return the SendResponse, which means you have opportunity to examine the SendResponse.ErrorMessages property, which is an IList<string>.  For myself, this is an opportunity to pass the error messages into Lurgle.Logging that can then turn into an OpsGenie alert via Seq.

If you were already using the bool response in code, you would just need to adjust this from:

                                var alert = Alert.To().Subject().Send("Test");
                              if (!alert)


                                var alert = Alert.To().Subject().Send("Test");
                              if (!alert.Successful)

Lurgling HTML, plain text, and HTML with alternate text

As I was revising code, I decided that we weren't handling emails that were plain text, HTML, or HTML with alternate text, as well as we should.

It's generally good practice to include both a HTML and plain text version of an email, and there's a number of RFCs covering this. Although "most" people can view HTML, you shouldn't necessarily assume that it's always the case. I felt existing functionality was somewhat limited here.

I've therefore baked plain text and HTML handling into Lurgle for all of the send methods. 

  • Send() and SendAsync() now assume plain text - they really always did, as such
  • SendHtml() and SendHtmlAsync() are new methods that allow sending HTML with optional alternate (plain) text
  • SendTemplate() and SendTemplateAsync() include optional parameter string alternateTemplate = null  that allows you to supply a plain text template for rendering as the alternate text
  • SendTemplateFile(), and SendTemplateFileAsync() now include optional parameter bool alternateText = false. If set to true, Lurgle will render the plain text version of your template (for example, alertTemplate.txt) as the alternate text, still allowing your selected renderer to act on the file!

Some usage examples:

                Alert.To().Subject("Test").Send("Can you fix it?");
                Alert.To().Subject("Test HTML")
                    .SendHtml("<html><body><p>Can you fix it?</p></body></html>", "Can you fix it?");
                Alert.To().Subject("Test Razor Template with alt text").SendTemplateFile("Razor", new { }, true, true);

For SendTemplateFile, the last two parameters are isHtml = true and alternateText = true. This means that Lurgle will load the alertRazor.html and alertRazor.txt files when rendering the email, render them with RazorLight, and add the alternate text view to your email.

Both of these render with RazorLight, so you can do all your usual work in the text version - it's just not as "pretty".  I've included samples of the two templates below,  from the LurgleTest and Lurgle.Alerting.Tests projects.


@using Lurgle.Alerting
<!DOCTYPE html>
<html lang="en" xmlns="">
  <meta charset="utf-8"/>
  <title>Razor Test</title>
  <style type="text/css">
      p, td {
          font-family: "Calibri", sans-serif;
          font-size: 11.0pt;
<p style="font-size: 14pt; font-weight: bold;">@Alerting.Config.AppName v@(Alerting.Config.AppVersion)</p>
  <table style="border: 0;">
          <td style="font-weight: bold;">Renderer:</td>
          <td style="font-weight: bold;">Sender:</td>
          <td style="font-weight: bold;">Template Path:</td>
          <td style="font-weight: bold;">Mail Host:</td>
          <td style="font-weight: bold;">Mail Port:</td>
          <td style="font-weight: bold;">Mail Test Timeout:</td>
          <td style="font-weight: bold;">Use Authentication:</td>
          <td style="font-weight: bold;">Username:</td>
          <td style="font-weight: bold;">Password:</td>
          <td style="font-weight: bold;">Use TLS:</td>
          <td style="font-weight: bold;">SMTP Timeout:</td>
          <td style="font-weight: bold;">Mail From:</td>
          <td style="font-weight: bold;">Mail To:</td>
          <td style="font-weight: bold;">Mail Debug:</td>
          <td style="font-weight: bold;">Mail Subject:</td>


@using Lurgle.Alerting
@Alerting.Config.AppName v@(Alerting.Config.AppVersion)

Renderer: @Alerting.Config.MailRenderer
Sender: @Alerting.Config.MailSender
Template Path: @Alerting.Config.MailTemplatePath
Mail Host: @Alerting.Config.MailHost
Mail Port: @Alerting.Config.MailPort
Mail Test Timeout: @(Alerting.Config.MailTestTimeout/1000)
Use Authentication: @Alerting.Config.MailUseAuthentication
Username: @Alerting.Config.MailUsername
Password: @Alerting.Config.MailPassword
Use TLS: @Alerting.Config.MailUseTls
SMTP Timeout: @(Alerting.Config.MailTimeout/1000)
Mail From: @Alerting.Config.MailFrom
Mail To: @Alerting.Config.MailTo
Mail Debug: @Alerting.Config.MailDebug
Mail Subject: @Alerting.Config.MailSubject

Retrieving rendered Lurgles

I also added several methods that allow retrieving a rendered email without sending. This is obviously useful for things like unit testing, but it also exposes the underlying IFluentEmail which means that you could do additional things with the email before sending.

The unit tests make use of this somewhat, like below:

            var alert = Alert.To().Subject("Test Razor Template").GetTemplateFile("Razor", new { }, true, true);
          Assert.True(alert.Data.Body.Length  > 0);
          Assert.True(alert.Data.PlaintextAlternativeBody.Length > 0);

Use the Lurgle, Luke (Get Lurgle.Alerting!)

The normal way to update is via Nuget, but man, we rock some fancy links around here too!



You may also like:

Lurgle.Logging v1.1.14 and Lurgle.Alerting v1.1.9 Released

I've pushed out updates to Lurgle.Logging and Lurgle.Alerting today. The Lurgle.Logging update is minor - I noticed that Log.Add wasn't correctly passing the calling method, source file, and line number. Lurgle.Alerting has received a more substantial update: This helps to make Lurgle.Alerting even more useful and reliable! You can get...

Lurgle.Alerting - a standardised FluentEmail implementation with extra goodies!

Another Lurgle Around the time that I tackled my original Serilog logging implementation, I also looked at our email alerting. Emails can be used for a variety of reasons, and it's not uncommon that they are sent as a simple string that concatenates or formats variables. In this scenario, the...

Event Timeout for Seq v1.4.2 released

A new release of Seq.App.EventTimeout is out. This was a little earlier than I planned to release v1.4.x, but there was a bug in the AbstractAPI deserialization as a result of some code refactoring which I'd missed. As usual, you can install Event Timeout for Seq using Seq.App.EventTimeout as the...