Template Emails in Net Core Demo

By Krystal Ruwoldt

Updated 11/15/2020


See the source code for this project:  

This demo ASP.NET Core 3.1 app uses NETCore.Mailkit package to send emails with custom templates for user authentication tasks and website contact forms. I wrote a detailed blog article about this demo as it is a real scenario solution I came up with after I found that SendGrid (as outlined in Spamhas.org!


Table of Contents


Overview

This demo app is slightly simplified as to what I use in my real website for the same purposes, as I wanted the main concepts in the blog article to be easily understood by even a beginner. It uses the MVC Web Application template included in Visual Studio with Scaffolded Authentication, along with the NETCore.MailKit package. I like how this package is easy to implement into an existing project where the purpose of automating the email is just for basic tasks, like verification emails or website contact forms.

I also wanted a solution for dynamically generating emails with HTML templates, that could be reused over the lifetime of the application. This project demonstrates how this can be achieved and makes use of a third-party online HTML template generator tool mail-signatures.com for the actual templates. The blog article outlines testing this demo project using PapercutSMTP, a simple email viewer (with a built-in SMTP server!) that I have found amazingly useful when debugging SMTP.

PapercutSMTP User Interface

A follow-up to the blog article is already planned, to include some improvements and other ideas that spawned from writing the blog article and creating the project.

Table of Contents


Features

Configuration

The project uses a fairly common method of configuring a SMTP service. The MailKit service is added via dependency injection as a scoped service, with configuration settings extracted from appsettings.json as service options. In this project I chose to use appsettings.json for simplicity's sake, while discussing other options for app secret storage in the blog article.

Startup.cs
...

services.AddMailKit(config => config.UseMailKit(

Configuration.GetSection("EmailSettings").Get<MailKitOptions>()));

...

Contact Forms in MVC and Razor Pages:

As the blog article connected to this project is written for beginner level, I wanted to demonstrate how a contact form can be generated in both MVC and Razor Pages. I find more often than not, both MVC and Razor Pages are used in the same application, so by implementing the exact same contact form in both shows the similarities and differences between each view.

Data Validation:

Contact forms have user input validated by using Data Annotation Attributes, and client-side by using jQuery. This is standard practice for ensuring data integrity.

Reusable HTML Email Templates:

Email templates are stored in the root folder of the app so that they can be dynamically generated as required for the task at hand. Not only are emails more professional with styling, further templates for a myriad of purposes can be added easily to the app, thereby allowing scaling of the project. The template folder path is stored in appsettings.json and injected via IConfiguration into classes that require the service.

DRY Principle:

I demonstrate in the blog article how to develop the logic behind creating and using a static 'helper' method to reduce code repetition. The helper method has the template name and path passed in as parameters and then uses System.IO StreamReader to open and read the file as a string that can then be manipulated in the class that uses the email service. The helper can then be used over any number of classes, should they need use of an email service.

EmailHelper.cs

using System.IO;

namespace SendTemplateEmailsDemo.Helpers

{

public class EmailHelper

{

public static string BuildTemplate(string path, string template)

{

StreamReader str = new StreamReader(Path.Combine(path, template));

string mailText = str.ReadToEnd();

str.Close();

return mailText;

}

}

}

Using the Email Service for Authentication

The project also demonstrates how to replace the default email service in scaffolded Identity classes with MailKit email service, and use a custom template for the email body. This shows that the same email service can be used for other email tasks, such as for a contact form.

Table of Contents


Improvements

Using SSL/TLS encryption on mail server

To use SSL/TLS relies on the mail server having such a security certificate. This can introduce another cost to running a website, as from my experience, a lot of hosts provide their clients with a mail server as part of their hosting plan but these 'included' servers are usually just SMTP servers. Some hosts offer a SSL/TLS mail server but these often use a 'shared' certificate, which introduces another level of complexity as a 'shared' certificate likely will throw validation errors when resolving the check on the certificate owner. I felt this was out of the scope of the blog article considering it was written for beginners. Hence this project uses clear text SMTP, which is common but has no encryption.

Logging, Errors & Further Testing

I would include unit tests in a real project, but this was outside the scope of the blog article. However I would like to improve this project by including error detection and using the built-in Logger throughout the email process. Error detection is an important topic to cover and needs to be implemented in real scenarios.

Notifications of Website Activity

Using automated emails for website action notification is something I have implemented in my live website since writing the blog article and creating this project. I'd like to include this topic in the next update of the project as not only this can be valuable to the website admin for analytics but also a way of getting prompt notification of issues in a production environment.

Better contact or enquiry forms

The contact form in this project is very simplified. Real website enquiry or contact forms usually use some kind of CAPTCHA service to distinguish between human and robot access. Using Google's ReCaptcha is very easy so this will be another feature added in the next update of the project. Together with error detection already discussed, the Contact Result Page can also be improved by displaying an actual result. I will also show how a contact form can include additional validation, such as consent for collection of user data (to achieve GDPR compliance).

Table of Contents


Conclusion & Planned Updates

I wrote the blog article hoping this will assist others (particularly those struggling to understand this vast topic of email automation). With so many APIs and other services available for all aspects of email automation, it can be overwhelming when just trying to figure out the basics! So I will follow-up this article and project with another in the series, as once basic concepts are understood and implemented it gets easier to extend and use automated email for a variety of purposes.

Next in the series:

  • Error Detection & Logging
  • Website Action Notifications
  • Improved Contact Pages - CAPTCHA, GDPR Compliance & Better Result Page
  • 'Get a Quote' Form
  • Creating Basic Marketing Emails

Table of Contents


These will be included in a future blog post and updated project - so stay tuned!