Send Email Using Templates In ASP.NET Core

In this article, we will discuss how to send emails using a Template file in ASP.NET Core Application. Sending email using Template file is similar to sending emails using plain text. The only difference is that now, the source of the content is a text file rather than direct content for email.

If you don’t know how to send email in ASP.NET Core applications, please refer to my previous article Configure Email Service In ASP.NET Core Using MailKit. Let's assume, we have already configured email service in ASP.NET Core application.

Milestones
  1. Create a Simple Email Template.
  2. Configure Email Setting in ASP.NET Core Application.
  3. Read content from Email Template using StreamReader()
  4. Personalize Email Content
  5. Send Email to User
Creating a Simple Email Template

We will keep the template file separate so that we can change the file design and content anytime. Let's keep these template files under wwwroot => Templates => EmailTemplate.

Step 1

For this, create a new folder named Templates under wwwroot folder.

Step 2

Create a new folder named Email Template under Templates folder.

Step 3

Add a new Item in Email Template (right click on Email Template folder >> add New Item).
Step 4

Select ASP.NET Core and then HTML Page.

Step 5

Set a name for the HTML file. In my case, I have named it as Welcome_EmailTemplate.html (But I will be using Confirm_Account_Registration.html for demo purposes whose design is the same with a different file name).
 

Send Email using Templates in ASP.NET Core Applications

Once you have created Email Templates, the Solution Explorer looks like below. (In my case, there are 5 Email Templates)

Send Email using Templates in ASP.NET Core Applications

 
Now, you can write your own design codes using inline CSS and HTML to create Email. In my case, the template looks like this -
 

Send Email using Templates in ASP.NET Core Applications

 
The code for the above sample Email Template is given below.

Code Snippet 
  1. <html xmlns="http://www.w3.org/1999/xhtml">  
  2. <head>  
  3.     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
  4.     <title>Welcome Email from TCP</title>  
  5. </head>  
  6.   
  7. <body>  
  8.     <table width="100%" border="0" cellspacing="0" cellpadding="0">  
  9.         <tr>  
  10.             <td align="center" valign="top" bgcolor="#ffe77b" style="background-color:#ffe77b;">  
  11.                 <br>  
  12.                 <br>  
  13.                 <table width="600" border="0" cellspacing="0" cellpadding="0">  
  14.                     <tr>  
  15.                         <td height="70" align="left" valign="middle"></td>  
  16.                     </tr>  
  17.                     <tr>  
  18.                         <td align="left" valign="top"><img src="http://localhost:2131/Templates/EmailTemplate/images/top.png" width="600" height="13" style="display:block;"></td>  
  19.                     </tr>  
  20.                     <tr>  
  21.                         <td align="left" valign="top" bgcolor="#564319" style="background-color:#564319; font-family:Arial, Helvetica, sans-serif; padding:10px;">  
  22.                             <div style="font-size:36px; color:#ffffff;">  
  23.                                 <b>{0}</b>  
  24.                             </div>  
  25.                             <div style="font-size:13px; color:#a29881;">  
  26.                                 <b>{1} : ASP.NET Core Demp App</b>  
  27.                             </div>  
  28.                         </td>  
  29.                     </tr>  
  30.                     <tr>  
  31.                         <td align="left" valign="top" bgcolor="#ffffff" style="background-color:#ffffff;">  
  32.                             <table width="100%" border="0" cellspacing="0" cellpadding="0">  
  33.                                 <tr>  
  34.                                     <td align="center" valign="middle" style="padding:10px; color:#564319; font-size:28px; font-family:Georgia, 'Times New Roman', Times, serif;">  
  35.                                         Congratulations! <small>You are registered.</small>  
  36.                                     </td>  
  37.                                 </tr>  
  38.                             </table>  
  39.                             <table width="95%" border="0" align="center" cellpadding="0" cellspacing="0">  
  40.                                 <tr>  
  41.                                     <td width="40%" align="center" valign="middle" style="padding:10px;">  
  42.                                         <img src="http://localhost:2131/Templates/EmailTemplate/images/Weak_Password.gif" width="169" height="187" style="display:block">  
  43.                                     </td>  
  44.                                     <td align="left" valign="middle" style="color:#525252; font-family:Arial, Helvetica, sans-serif; padding:10px;">  
  45.                                         <div style="font-size:16px;">  
  46.                                             Dear {2},  
  47.                                         </div>  
  48.                                         <div style="font-size:12px;">  
  49.                                             Thank you for showing your interest  in  our website.  
  50.                                             All you need to do is click the button below (it only takes a few seconds).  
  51.                                             You won’t be asked to log in to your account – we're simply verifying ownership of this email address.  
  52.                                             <hr>  
  53.                                             <center>  
  54.   
  55.                                                 <button type="button" title="Confirm Account Registration" style="background: #1b97f1">  
  56.                                                     <a href="{6}" style="font-size:22px; padding: 10px; color: #ffffff">  
  57.                                                         Confirm Email Now  
  58.                                                     </a>  
  59.                                                 </button>  
  60.   
  61.                                             </center>  
  62.                                         </div>  
  63.                                     </td>  
  64.                                 </tr>  
  65.                             </table>  
  66.                             <table width="100%" border="0" cellspacing="0" cellpadding="0">  
  67.                                 <tr>  
  68.                                     <td align="center" valign="middle" style="padding:5px;">  
  69.                                         <img src="http://localhost:2131/Templates/EmailTemplate/images/divider.gif" width="566" height="30">  
  70.                                     </td>  
  71.                                 </tr>  
  72.                             </table>  
  73.                             <table width="100%" border="0" align="center" cellpadding="0" cellspacing="0" style="margin-bottom:15px;">  
  74.                                 <tr>  
  75.                                     <td align="left" valign="middle" style="padding:15px; font-family:Arial, Helvetica, sans-serif;">  
  76.                                         <div style="font-size:20px; color:#564319;">  
  77.                                             <b>Please keep your credentials confidential for future use. </b>  
  78.                                         </div>  
  79.                                         <div style="font-size:16px; color:#525252;">  
  80.                                             <b>Email         :</b> {2}  
  81.                                             <br />  
  82.                                             <b>Username :</b> {3}  
  83.                                             <br />  
  84.                                             <b>Password :</b> {4}  
  85.                                         </div>  
  86.                                     </td>  
  87.                                 </tr>  
  88.                             </table>  
  89.                             <table width="100%" border="0" cellspacing="0" cellpadding="0" style="margin-bottom:10px;">  
  90.                                 <tr>  
  91.                                     <td align="left" valign="middle" style="padding:15px; background-color:#564319; font-family:Arial, Helvetica, sans-serif;">  
  92.                                         <div style="font-size:20px; color:#fff;">  
  93.                                             <b>Update your password now.</b>  
  94.                                         </div>  
  95.                                         <div style="font-size:13px; color:#ffe77b;">  
  96.                                             Weak passwords get stolen and lead to hacked accounts. Celebrate World Password Day with a new, strong password.  
  97.                                             <br>  
  98.                                             <br>  
  99.                                             <a href="#" style="color:#ffe77b; text-decoration:underline;">CLICK HERE</a> TO CHANGE PASSOWORD  
  100.                                         </div>  
  101.                                     </td>  
  102.                                 </tr>  
  103.                             </table>  
  104.                             <table width="95%" border="0" align="center" cellpadding="0" cellspacing="0">  
  105.                                 <tr>  
  106.                                     <td width="50%" align="left" valign="middle" style="padding:10px;">  
  107.                                         <table width="75%" border="0" cellspacing="0" cellpadding="4">  
  108.                                             <tr>  
  109.                                                 <td align="left" valign="top" style="font-family:Verdana, Geneva, sans-serif; font-size:14px; color:#000000;">  
  110.                                                     <b>Follow Us On</b>  
  111.                                                 </td>  
  112.                                             </tr>  
  113.                                             <tr>  
  114.                                                 <td align="left" valign="top" style="font-family:Verdana, Geneva, sans-serif; font-size:12px; color:#000000;">  
  115.                                                     <table width="100%" border="0" cellspacing="0" cellpadding="0">  
  116.                                                         <tr>  
  117.                                                             <td width="33%" align="left" valign="middle">  
  118.                                                                 <a href="https://twitter.com" title="Facebook">  
  119.                                                                     <img src="http://localhost:2131/Templates/EmailTemplate/images/tweet48.png" width="48" height="48">  
  120.                                                                 </a>  
  121.                                                             </td>  
  122.                                                             <td width="34%" align="left" valign="middle">  
  123.                                                                 <a href="https://linkedin.com" title="Linkedin">  
  124.                                                                     <img src="http://localhost:2131/Templates/EmailTemplate/images/in48.png" width="48" height="48">  
  125.                                                                 </a>  
  126.                                                             </td>  
  127.                                                             <td width="33%" align="left" valign="middle">  
  128.                                                                 <a href="https://facebook.com" title="Facebook">  
  129.                                                                     <img src="http://localhost:2131/Templates/EmailTemplate/images/face48.png" width="48" height="48">  
  130.                                                                 </a>  
  131.                                                             </td>  
  132.                                                         </tr>  
  133.                                                     </table>  
  134.                                                 </td>  
  135.                                             </tr>  
  136.                                         </table>  
  137.                                     </td>  
  138.                                     <td width="50%" align="left" valign="middle" style="color:#564319; font-size:11px; font-family:Arial, Helvetica, sans-serif; padding:10px;">  
  139.                                         <b>Hours:</b> Mon-Fri 9:30-5:30, Sat. 9:30-3:00, Sun. Closed <br>  
  140.                                         <b>Customer Support:</b> <a href="mailto:[email protected]" style="color:#564319; text-decoration:none;">[email protected]</a><br>  
  141.                                         <br>  
  142.                                         <b>Company Address</b><br>  
  143.                                         Company URL: <a href="http://www.yourcompanyname.com" target="_blank" style="color:#564319; text-decoration:none;">http://www.yourcompanyname.com</a>  
  144.                                     </td>  
  145.                                 </tr>  
  146.                             </table>  
  147.                         </td>  
  148.                     </tr>  
  149.                     <tr>  
  150.                         <td align="left" valign="top"><img src="http://localhost:2131/Templates/EmailTemplate/images/bot.png" width="600" height="37" style="display:block;"></td>  
  151.                     </tr>  
  152.                 </table>  
  153.                 <br>  
  154.                 <br>  
  155.             </td>  
  156.         </tr>  
  157.     </table>  
  158. </body>  
  159. </html>   
Now, our Email Template is ready.

Scenario - I : Verifying User's Email Ownership on Registration

We need to send a confirmation email to verify the ownership of the email to the user,  just after first registration with his/her email on our application.

The process is,
  • Collect user details from Registration Form
  • Register Method of Account Controller of type [HttpPost] creates a new user using the following code.
    1. //Take user details from Registration Form ie. model carries data from Registration form to here
    2. var user = new ApplicationUser { UserName = model.Email, Email = model.Email };

    3. //CreateAsync inside UserManager creates new user when userdetails and password supplied.
    4. var result = await _userManager.CreateAsync(user, model.Password);
  • Generate unique code for new user details.
    1. var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
  • A unique random callbackUrl is generated using the generated code and UserId.
    1. var callbackUrl = Url.Action(nameof(ConfirmEmail), "Account", new { userId = user.Id, code = code }, protocol: HttpContext.Request.Scheme);
  • Send callbackUrl to the user via email.
    1. string Message = "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>";
    2. //Send Email to User
    3. await _emailSender.SendEmailAsync(model.Email, subject, messageBody);
  • When user clicks the send callback URL, he/she is sent back to the ConfirmEmail Method of Account Controller.
  1. //Find User Details by userId
  2. var user = await _userManager.FindByIdAsync(userId);
  3. if (user == null)
  4. {
  5. return View("Error");
  6. }
  7. var result = await _userManager.ConfirmEmailAsync(user, code);
  8. ViewData["Message"] = "Your email has been confirmed. Please Login now. ";
  9. ViewData["MessageValue"] = "1";
  • This line will match the received user details and code via callbackUrl and sets ConfirmedEmail to true in database.
Now, during this process, if we want to send email using our custom Email Templates, we need to
  1. Read content of Email Template
  2. Read User Details received from User Registration Form.
  3. Pass User Details to contents of Email Template.
  4. Replace {0}, {1}, {2} with respective values.
  5. Send email to user. (Using Mail Kit for now)
Reading Contents from Template File

Step 1

Get Information about the web Hosting Environment where our application is running. 
  1.        private readonly UserManager<ApplicationUser> _userManager;  
  2.        private readonly SignInManager<ApplicationUser> _signInManager;  
  3.        private readonly IEmailSender _emailSender;  
  4.        private readonly ISmsSender _smsSender;  
  5.        private readonly ILogger _logger;  
  6.        private readonly string _externalCookieScheme;  
  7.        private IHostingEnvironment _env;  
  8.   
  9.        public AccountController(  
  10.            UserManager<ApplicationUser> userManager,  
  11.            SignInManager<ApplicationUser> signInManager,  
  12.            IOptions<IdentityCookieOptions> identityCookieOptions,  
  13.            IEmailSender emailSender,  
  14.            ISmsSender smsSender,  
  15.            ILoggerFactory loggerFactory, 
  16.  
  17.            IHostingEnvironment env)  
  18.        {  
  19.            _userManager = userManager;  
  20.            _signInManager = signInManager;  
  21.            _externalCookieScheme = identityCookieOptions.Value.ExternalCookieAuthenticationScheme;  
  22.            _emailSender = emailSender;  
  23.            _smsSender = smsSender;  
  24.            _logger = loggerFactory.CreateLogger<AccountController>(); 
  25.  
  26.            _env = env;  
  27.        }   
Step 2

get wwwroot Folder
  1. var webRoot = _env.WebRootPath; //get wwwroot Folder
Step 3

Get TemplateFile located at wwwroot/Templates/EmailTemplate/Register_EmailTemplate.html 
  1. //Get TemplateFile located at wwwroot/Templates/EmailTemplate/Register_EmailTemplate.html  
  2.                     var pathToFile = _env.WebRootPath  
  3.                             + Path.DirectorySeparatorChar.ToString()  
  4.                             + "Templates"  
  5.                             + Path.DirectorySeparatorChar.ToString()  
  6.                             + "EmailTemplate"  
  7.                             + Path.DirectorySeparatorChar.ToString()  
  8.                             + "Confirm_Account_Registration.html";   
Step 4

Initialie BoduBuilder()
  1. var builder = new BodyBuilder();
Step 5

Read Content of Template file using StreamReader and append to BodyBuilder()
  1. using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile))
  2. {

  3. builder.HtmlBody = SourceReader.ReadToEnd();

  4. }

Passing value and Formatting the Content of Template with Dynamic Values

Step 1

use string.Format(format item, dynamic values as parameters) In our case, {x} values in Templates are to replace by dynamic values.
  1. //{0} : Subject  
  2. //{1} : Current DateTime  
  3. //{2} : Email  
  4. //{3} : Username  
  5. //{4} : Password  
  6. //{5} : Message  
  7. //{6} : callbackURL  
Code Snippet
  1. string messageBody = string.Format(builder.HtmlBody,   
  2.                         subject,  
  3.                         String.Format("{0:dddd, d MMMM yyyy}", DateTime.Now),  
  4.                         model.Email,   
  5.                         model.Email,   
  6.                         model.Password,   
  7.                         Message,  
  8.                         callbackUrl  
  9.                         );  
Send Email using Mailkit

If you don’t know how to send email using Mail kit in ASP.NET Core Applications please refer to my previous blog. For now I am skipping setting up email service.
  1. await _emailSender.SendEmailAsync(model.Email, subject, messageBody);  
  2. //Success Message ViewData["Message"] = $"Please confirm your account by clicking this link: <a href='{callbackUrl}' class='btn btn-primary'>Confirmation Link</a>";  
  3. ViewData["MessageValue"] = "1";  
await _emailSender.SendEmailAsync(model.Email, subject, messageBody); line will send email to user email.

Code used in Register Method of Account Controller

  1. // POST: /Account/Register  
  2.         [HttpPost]  
  3.         [AllowAnonymous]  
  4.         [ValidateAntiForgeryToken]  
  5.         public async Task<IActionResult> Register(RegisterViewModel model, string returnUrl = null)  
  6.         {  
  7.             ViewData["ReturnUrl"] = returnUrl;  
  8.             if (ModelState.IsValid)  
  9.             {  
  10.                 var user = new ApplicationUser { UserName = model.Email, Email = model.Email };  
  11.                 var result = await _userManager.CreateAsync(user, model.Password);  
  12.   
  13.                 // var user = await _userManager.FindByEmailAsync(model.Email);  
  14.                 if (result.Succeeded)  
  15.                 {  
  16.                     // Send an email with this link  
  17.                     var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);  
  18.                     var callbackUrl = Url.Action(nameof(ConfirmEmail), "Account"new { userId = user.Id, code = code }, protocol: HttpContext.Request.Scheme);  
  19.                     //Email from Email Template  
  20.                     string Message = "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>";  
  21.                    // string body;  
  22.   
  23.                     var webRoot = _env.WebRootPath; //get wwwroot Folder  
  24.   
  25.                     //Get TemplateFile located at wwwroot/Templates/EmailTemplate/Register_EmailTemplate.html  
  26.                     var pathToFile = _env.WebRootPath  
  27.                             + Path.DirectorySeparatorChar.ToString()  
  28.                             + "Templates"  
  29.                             + Path.DirectorySeparatorChar.ToString()  
  30.                             + "EmailTemplate"  
  31.                             + Path.DirectorySeparatorChar.ToString()  
  32.                             + "Confirm_Account_Registration.html";  
  33.   
  34.                     var subject = "Confirm Account Registration";  
  35.   
  36.                     var builder = new BodyBuilder();  
  37.                     using (StreamReader SourceReader = System.IO.File.OpenText(pathToFile))  
  38.                     {  
  39.                         builder.HtmlBody = SourceReader.ReadToEnd();  
  40.                     }  
  41.                     //{0} : Subject  
  42.                     //{1} : DateTime  
  43.                     //{2} : Email  
  44.                     //{3} : Username  
  45.                     //{4} : Password  
  46.                     //{5} : Message  
  47.                     //{6} : callbackURL  
  48.   
  49.                     string messageBody = string.Format(builder.HtmlBody,   
  50.                         subject,  
  51.                         String.Format("{0:dddd, d MMMM yyyy}", DateTime.Now),  
  52.                         model.Email,   
  53.                         model.Email,   
  54.                         model.Password,   
  55.                         Message,  
  56.                         callbackUrl  
  57.                         );  
  58.   
  59.   
  60.                     await _emailSender.SendEmailAsync(model.Email, subject, messageBody);  
  61.   
  62.                     ViewData["Message"] = $"Please confirm your account by clicking this link: <a href='{callbackUrl}' class='btn btn-primary'>Confirmation Link</a>";  
  63.                     ViewData["MessageValue"] = "1";  
  64.   
  65.                     _logger.LogInformation(3, "User created a new account with password.");  
  66.                     return RedirectToLocal(returnUrl);  
  67.                 }  
  68.                 ViewData["Message"] = $"Error creating user. Please try again later";  
  69.                 ViewData["MessageValue"] = "0";  
  70.                 AddErrors(result);  
  71.             }  
  72.   
  73.             // If we got this far, something failed, redisplay form  
  74.             return View(model);  
  75.         }   
Appplication Execution and Output
 
Step 1

Now let's rebuild the soution and run the application.

Step 2

Lets register as a New user /Account/Register
Send Email using Templates in ASP.NET Core Applications
Once we register as new user, a confirmation email is sent on the registred email. Upon checking the email inbox, we receive email like this -

Send Email using Templates in ASP.NET Core Applications

We receive the personalized email sent from the Demo ASP.NET Core Application.

Scenerio where we need Email Templates
  • Send personalized emails to all/selected users for events and news.
  • Newsletter
  • Notices and Call for events
  • Welcome Email to New Users.
  • Automatic Monthly report to Admins and Staffs.
  • and many more....
Summary

So far, we have learned how to send personalized emails to users creating Email Templates .

You may also like