Account Confirmation with an ASP.NET MVC Identity using an Email Template

Introduction

This post explains account confirmation with an ASP.NET MVC identity using an email template.

Prerequisites

- Knowledge of ASP.NET Identity
- Knowledge of ASP.NET MVC
 
Overview 
I have created a sample ASP.NET MVC application with an identity. In this project, I will add features for account confirmation using an email template
 
  
 
Let's start our project. Create a new MVC project, as shown below
 
  
 
Now, enter a project name and select the project location and framework.
 
  
Click on the "Create" button. Now select the MVC application and authentication
 
 
 
Now, change authentication from "no authentication" to "individual user accounts" and click on the "Create" Button.
 
  
 
Now, your project is created successfully.
Go to web.config and write the connection string:
 
  1. <connectionStrings>  
  2. <add name="Connect" connectionString="Data Source=*****; User id=****;password=****;Database=Demo" providerName="System.Data.SqlClient" />  
  3. </connectionStrings>  
Now, we create a send email functionality. Add a utility folder and create a SendEmail Class. In this method, we get Host,MailForm, Password and Port from a Web.Config File.
  1. using System;  
  2. using System.Configuration;  
  3. using System.Net;  
  4. using System.Net.Mail;  
  5. namespace DemoAccount.Utility  
  6. {  
  7. public class SendEmail  
  8. {  
  9. public static bool EmailSend(string SenderEmail, string Subject, string Message, bool IsBodyHtml = false)  
  10. {  
  11. bool status = false;  
  12. try  
  13. {  
  14. string HostAddress = ConfigurationManager.AppSettings["Host"].ToString();  
  15. string FormEmailId = ConfigurationManager.AppSettings["MailFrom"].ToString();  
  16. string Password = ConfigurationManager.AppSettings["Password"].ToString();  
  17. string Port = ConfigurationManager.AppSettings["Port"].ToString();  
  18. MailMessage mailMessage = new MailMessage();  
  19. mailMessage.From = new MailAddress(FormEmailId);  
  20. mailMessage.Subject = Subject;  
  21. mailMessage.Body = Message;  
  22. mailMessage.IsBodyHtml = IsBodyHtml;  
  23. mailMessage.To.Add(new MailAddress(SenderEmail));  
  24. SmtpClient smtp = new SmtpClient();  
  25. smtp.Host = HostAddress;  
  26. smtp.EnableSsl = true;  
  27. NetworkCredential networkCredential = new NetworkCredential();  
  28. networkCredential.UserName = mailMessage.From.Address;  
  29. networkCredential.Password = Password;  
  30. smtp.UseDefaultCredentials = true;  
  31. smtp.Credentials = networkCredential;  
  32. smtp.Port = Convert.ToInt32(Port);  
  33. smtp.Send(mailMessage);  
  34. status = true;  
  35. return status;  
  36. }  
  37. catch(Exception e)  
  38. {  
  39. return status;  
  40. }  
  41. }  
  42. }  
  43. }  
For the mail host setting in the config file.
  1. <appSettings>  
  2. <add key="Host" value="smtp.gmail.com" />  
  3. <add key="Port" value="587" />  
  4. <add key="MailFrom" value="From-Email" />  
  5. <add key="Password" value="From-Password" />  
  6. </appSettings>  
Here is account confirmation HTML template. In this template, I used Inline CSS.
The email and link are dynamic, so we have to add a value custom identity, such as {UserName} and {ConfirmationLink}
 
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  2. <html xmlns="http://www.w3.org/1999/xhtml" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">  
  3. <head>  
  4. <meta name="viewport" content="width=device-width" />  
  5. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />  
  6. <title>WSS</title>  
  7. <style type="text/css">  
  8. img {  
  9. max-width: 100%;  
  10. }  
  11. body {  
  12. -webkit-font-smoothing: antialiased;  
  13. -webkit-text-size-adjust: none;  
  14. width: 100% !important;  
  15. height: 100%;  
  16. line-height: 1.6em;  
  17. }  
  18. body {  
  19. background-color: #f6f6f6;  
  20. }  
  21. @media only screen and (max-width: 640px) {  
  22. body {  
  23. padding: 0 !important;  
  24. }  
  25. h1 {  
  26. font-weight: 800 !important;  
  27. margin: 20px 0 5px !important;  
  28. }  
  29. h2 {  
  30. font-weight: 800 !important;  
  31. margin: 20px 0 5px !important;  
  32. }  
  33. h3 {  
  34. font-weight: 800 !important;  
  35. margin: 20px 0 5px !important;  
  36. }  
  37. h4 {  
  38. font-weight: 800 !important;  
  39. margin: 20px 0 5px !important;  
  40. }  
  41. h1 {  
  42. font-size: 22px !important;  
  43. }  
  44. h2 {  
  45. font-size: 18px !important;  
  46. }  
  47. h3 {  
  48. font-size: 16px !important;  
  49. }  
  50. .container {  
  51. padding: 0 !important;  
  52. width: 100% !important;  
  53. }  
  54. .content {  
  55. padding: 0 !important;  
  56. }  
  57. .content-wrap {  
  58. padding: 10px !important;  
  59. }  
  60. .invoice {  
  61. width: 100% !important;  
  62. }  
  63. }  
  64. </style>  
  65. </head>  
  66. <body itemscope itemtype="http://schema.org/EmailMessage" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6em; background-color: #f6f6f6; margin: 0;" bgcolor="#f6f6f6">  
  67. <table class="body-wrap" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; width: 100%; background-color: #f6f6f6; margin: 0;" bgcolor="#f6f6f6">  
  68. <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">  
  69. <td style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;" valign="top"></td>  
  70. <td class="container" width="600" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; display: block !important; max-width: 600px !important; clear: both !important; margin: 0 auto;" valign="top">  
  71. <div class="content" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; max-width: 600px; display: block; margin: 0 auto; padding: 20px;">  
  72. <table class="main" width="100%" cellpadding="0" cellspacing="0" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; border-radius: 3px; background-color: #fff; margin: 0; border: 1px solid #e9e9e9;" bgcolor="#fff">  
  73. <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">  
  74. <td class="alert alert-warning" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 16px; vertical-align: top; color: #fff; font-weight: 500; text-align: center; border-radius: 3px 3px 0 0; background-color: #3c8dbc; margin: 0; padding: 20px;" align="center" bgcolor="#FF9F00" valign="top">  
  75. Account Confirmation  
  76. </td>  
  77. </tr>  
  78. <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">  
  79. <td class="content-wrap" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 20px;" valign="top">  
  80. <table width="100%" cellpadding="0" cellspacing="0" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">  
  81. <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">  
  82. <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">  
  83. Hello, <strong style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">{UserName}</strong>  
  84. </td>  
  85. </tr>  
  86. <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">  
  87. <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">  
  88. Please click bellow button for confirm your account.  
  89. </td>  
  90. </tr>  
  91. <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">  
  92. <td class="content-block" style="">  
  93. <a href="{ConfirmationLink}" class="btn-primary" style="background-color: #3c8dbc; border: none;color: white; padding: 10px 41px;text-align: center;text-decoration: none;display: inline-block; font-size: 16px;margin: 4px 2px;cursor: pointer;">Confirmation Link </a>  
  94. </td>  
  95. </tr>  
  96. <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">  
  97. <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">  
  98. <br /><b>Thanks & Regards,</b><br />  
  99. Pritesh N Maturkar<br />  
  100. </td>  
  101. </tr>  
  102. </table>  
  103. </td>  
  104. </tr>  
  105. </table><div class="footer" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; width: 100%; clear: both; color: #999; margin: 0; padding: 20px;">  
  106. <table width="100%" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">  
  107. <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">  
  108. <td class="aligncenter content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; vertical-align: top; color: #999; text-align: center; margin: 0; padding: 0 0 20px;" align="center" valign="top"></td>  
  109. </tr>  
  110. </table>  
  111. </div>  
  112. </div>  
  113. </td>  
  114. <td style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;" valign="top"></td>  
  115. </tr>  
  116. </table>  
  117. </body>  
  118. </html>  
Here is the registration method for registration of a user account and sending a confirmation email. In this register method, create a user using the ASP.NET identity method. Also, we need to add a user role in this method. First, create a role and then assign it to the user. Then, send an email confirmation link on the registration time. For send an email confirmation link, first get the HTML template and add a dynamic value, such as a username confirmation link. The ASP.NET identity generates a call-back URL, which sends in the email.
 
  1. // POST: /Account/Register  
  2. [HttpPost]  
  3. [AllowAnonymous]  
  4. [ValidateAntiForgeryToken]  
  5. public async Task<ActionResult> Register(RegisterViewModel model)  
  6. {  
  7. if (ModelState.IsValid)  
  8. {  
  9. var user = new ApplicationUser { UserName = model.Email, Email = model.Email };  
  10. ApplicationDbContext context = new ApplicationDbContext();  
  11. var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));  
  12. if (!roleManager.RoleExists("Admin"))  
  13. {  
  14. var role = new Microsoft.AspNet.Identity.EntityFramework.IdentityRole();  
  15. role.Name = "Admin";  
  16. roleManager.Create(role);  
  17. }  
  18. var result = await UserManager.CreateAsync(user, model.Password);  
  19. if (result.Succeeded)  
  20. {  
  21. var result1 = UserManager.AddToRole(user.Id, "Admin");  
  22. await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);  
  23. string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);  
  24. var callbackUrl = Url.Action("ConfirmEmail""Account"new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);  
  25. // await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>");  
  26. string body = string.Empty;  
  27. using (StreamReader reader = new StreamReader(Server.MapPath("~/MailTemplate/AccountConfirmation.html")))  
  28. {  
  29. body = reader.ReadToEnd();  
  30. }  
  31. body = body.Replace("{ConfirmationLink}", callbackUrl);  
  32. body = body.Replace("{UserName}", model.Email);  
  33. bool IsSendEmail = SendEmail.EmailSend(model.Email, "Confirm your account", body, true);  
  34. if(IsSendEmail)  
  35. return RedirectToAction("Login""Account");  
  36. }  
  37. AddErrors(result);  
  38. }  
  39. // If we got this far, something failed, redisplay form  
  40. //return View(model);  
  41. return RedirectToAction("Login""Account");  
  42. }  
Registration has created an identity table in your database
 
 
 
 
Now, on the login page, we check if the user account email is confirmed or not. Here is the login method in the account controller. In the login method, first, get the user base on email. Then, we check the user email confirmation. The ASP.NET Identity provides a method (IsEmailConfirmedAsync) for checking if the user email is confirmed or not.
  1. // POST: /Account/Login  
  2. [HttpPost]  
  3. [AllowAnonymous]  
  4. [ValidateAntiForgeryToken]  
  5. public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)  
  6. {  
  7. if (!ModelState.IsValid)  
  8. {  
  9. return View(model);  
  10. }  
  11. var user = await UserManager.FindByEmailAsync(model.Email);  
  12. if (user != null)  
  13. {  
  14. if (!await UserManager.IsEmailConfirmedAsync(user.Id))  
  15. {  
  16. ModelState.AddModelError("""You must have a confirmed email to log on.");  
  17. return View();  
  18. }  
  19. }  
  20. // This doesn't count login failures towards account lockout  
  21. // To enable password failures to trigger account lockout, change to shouldLockout: true  
  22. var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);  
  23. switch (result)  
  24. {  
  25. case SignInStatus.Success:  
  26. return RedirectToLocal(returnUrl);  
  27. case SignInStatus.LockedOut:  
  28. return View("Lockout");  
  29. case SignInStatus.RequiresVerification:  
  30. return RedirectToAction("SendCode"new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });  
  31. case SignInStatus.Failure:  
  32. default:  
  33. ModelState.AddModelError("""Invalid login attempt.");  
  34. return View(model);  
  35. }  
  36. }  
Now, press F5 and run the project.
 
 
 
Now, click on register.
 
 
 
After registration, send account confirmation via email. For confirmation, you need to click on the link. When we click on the link, it calls the account confirm method and updates the email confirmation field in the database.
 
 
 
Now, go to the login page. 
 
 
 
[Note: If the user is not confirmed, then the account will display the above message]. Here is the reference link
 
I hope, you liked this blog. If you have any doubts, you can ask me and I will try to answer your questions.
Next Recommended Reading TagBuilder class in ASP.NET MVC