Referbruv!


Card image cap

Template based Emails - Sending HTML Content over Email Using MailKit

ASP.NET Core  • Posted 3 months ago

In a previous article, we have seen how we can render and extract a razor view HTML with dynamic data by means of ASP.NET Core's useful razor engine library. The goal is to be able send a mail containing a table of reader data which is to be fed from the database by the API when invoked. In this article, let's continue on the journey and see how we can translate the HTML content we received from the previous step into an email content body. For this we shall take help from one of the most useful SMTP libraries available for ASP.NET Core.

Setting up the Context - What is an SMTP:

SMTP stands for Simple Mail Transmission Protocol, which is the architecture defined to send electronic-mails aka e-mails over the interconnected network or the Internet. Each receipt holds a unique identifier for the mails to be sent and received which we call as the email addresses. And there are tons of email providers such as Google, Yahoo, Microsoft and so on which are actually the email hosted servers through which the transmission happens. When we send out a mail to some bro@aka.com, it internally translates that the recipient is a person of the identifier bro under the email provider server called by the domain aka.com. The message packets are sent to the mail server under the domain aka.com via the SMTP protocol channel and internally the mail server delivers to the specified identifier account.

So now for to implement the mail sending feature, we shall require a mail server and a recipient address to which the system shall send out a mail. We shall simulate the process of composing and clicking on the send button by using an SMTP library which contain methods that do exactly the same: generating a mail packet and then invoking the domain mail server we configure on the library to send the mail packet to the recipient for us. ASP.NET provides this functionality via the System.Mail library but these days it has become so obsolete that the IDEs suggest to move on to the next popular library available for the ASP.NET Core which is MailKit.

MailKit requires another library called MimeKit which provides library for content handling while composing mails. We get started on the library by installing the packages using the below Cli commands


> dotnet add package MailKit --version="2.1.3"
> dotnet add package MimeKit --version="2.1.3"

Once the installation is done, let's begin by adding a MailHelper class which encapsulates the mail sending code for us.

Let's add an interface which provides the design abstraction as below.


namespace ReadersApi.Providers
{
    public interface IMailHelper
    {
        void SendMail(string to, string subject, string content);
    }
}

The interface defines one method SendMail which accepts the recepient for the mail, the subject of the mail and the content to be used for sending the mail.

The definition is shown as below.


namespace ReadersApi.Providers
{
    public class MailHelper : IMailHelper
    {
        IConfiguration configuration;

        public MailHelper(IConfiguration configuration)
        {
            this.configuration = configuration;
        }

        public void SendMail(string to, string subject, string messageContent)
        {
            string fromAddress = configuration["SmtpConfig:FromAddress"];
            string serverAddress = configuration["SmtpConfig:ServerAddress"];
            string username = configuration["SmtpConfig:Username"];
            string password = configuration["SmtpConfig:Password"];
            int port = Convert.ToInt32(configuration["SmtpConfig:Port"]);
            bool isUseSsl = Convert.ToBoolean(configuration["SmtpConfig:IsUseSsl"]);

            try
            {

                var message = new MimeMessage();
                message.From.Add(new MailboxAddress(from, from));
                message.To.Add(new MailboxAddress(to, to));
                message.Subject = subject;
                message.Body = new TextPart("html")
                {
                    Text = messageContent
                };

                using (var client = new MailKit.Net.Smtp.SmtpClient())
                {
                    client.Connect(serverAddress, port, isUseSsl);
                    client.Authenticate(username, password);
                    client.Send(message);
                    client.Disconnect(true);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }
    }
}

This simple functionality creates a new MimeMessage() instance and adds the necessary information such as the server address of the mail server (ex: mail.google.com), the recipient email address, the port of the smtp server (ex. 25) and so on. These are fed into the method by means of Configuration and the values are maintained under the appsettings json file. Also observe that we are declaring the content body of type "HTML" which indicates that whatever html document we pass will be parsed and rendered over the message body. This facilitates for all the styles we shall apply over the html document we send.

Lastly, we end by placing this MimeMessage() object over an SmtpClient() object created and sent over by calling the Send() method.

Now that this is done, we complete this by adding this MailHelper as a service under the ConfigureServices() method in Startup.cs


 services.AddSingleton<IMailHelper, MailHelper>();

And then, in the Controller method we have written to test, we add some more logic to pass the extracted html text to the mailHelper.SendMail() method.


namespace ReadersApi.Controllers
{
    [Route("api/[controller]")]
    public class LogicController : ControllerBase
    {
        private ITemplateHelper _templateHelper;
        private IMailHelper _mail;
        private IHostingEnvironment _environment;

        public LogicController(ITemplateHelper helper, IMailHelper mail, IHostingEnvironment environment)
        {
            _templateHelper = helper;
            _mail = mail;
            _environment = environment;
        }

        [HttpGet]
        [Route("template")]
        public async Task<string> GetTemplate()
        {
            var model = new MailViewModel();

            model.Data = ReaderStore.Readers;

            var response = await _templateHelper.GetTemplateHtmlAsStringAsync<MailViewModel>("Templates/Content", model);

            _mail.SendMail("bro@aka.com", "Reader Test Data", response);

            return response;
        }
    }

    public class MailViewModel
    {
        public string HeaderImage { get; set; }
        public List<Reader> Data { get; set; }
        public string FooterImage { get; set; }
    }
}

Observe that the Template Renderer now receives a ViewModel of type MailViewModel which also includes a header and a footer image. This setup is used to inflate the razor view with data and then the extracted html string is passed on to the mailHelper.SendMail() method which processes and sends out an email. The final mail can look like below:

data/Admin/2019/12/Mail.PNG

In this way we can send a html document as body to a mail. Next, we shall see how we can take this to the next level, by adding images into our mails which can garner better user engagement and attention. Let's look at that in the next article.

Published 3 months ago

Sponsored Links
We use cookies to improve user experience. Learn More