(C# ASP.NET Core) Resending an Account Verification EMail in Identity based Authentication

As soon as a new user registers on a website, an account verification email or an sms is immediately sent to him. But it is possible that a user never receives the email, or perhaps he is unable to locate the email that he might have received a few days back. Such a user would ask for the confirmation link to be sent again. This means that we need a mechanism for resending an email to a user. This tutorial explains the steps needed to generate and resend the link to that user.
(Rev. 19-Mar-2024)

Categories | About |     |  

Parveen,

Table of Contents (top down ↓)

The Plan of Implmentation

Let's have a look at the plan.

First of all we will ask the user to enter his email and submit the form to our server.

On the server side this email will be used to obtain the IdentityUser record. Then, this instance will be used to generate an email confirmation token. And, the token will, in turn, be used to construct the email confirmation link which will be emailed or sent to the user in an sms message.

Video Explanation (see it happen!)

Please watch the following youtube video:

Add the Resend EMail Confirmation Page

Our first step is to add a page for the resend email functionality. So, locate the auth area and add a page called ResendEMailConfirmation.

We can now examine the markup for this page.

// Areas -> Auth -> Pages -> ResendEMailConfirmation.cshtml 

@page

@model MyRazorApp.Areas.Auth.Pages.ResendEMailConfirmationModel

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

<h1>Please type EMail to Receive Confirmation EMail</h1>

<div style="color:red" asp-validation-summary="All"></div>

<form method="post">

  <table>

    <tr>
      <td>
        <label asp-for="UserID"></label>
      </td>
      <td>
        <input asp-for="UserID" />
      </td>
      <td>
        <span asp-validation-for="UserID"></span>
      </td>
    </tr>

    <tr>
      <td colspan="2" style="text-align:right">
        <input type="submit" value="Send!" />
      </td>
    </tr>

  </table>

</form>

  

First we have the customary directives for model, addTagHelper.

Then we have a tag for the validation summary.

An html table has been used for creating the form. The first tr is for the email input text box. This input is connected to a bind property called UserID. This property will carry the email to the server side.

Then, we have a submit button. We have kept the form brief and simple by avoiding any css and javascript, which can always be added with the help of designer teams.

Next, let us come to the backing class. Double click the ResendEMailConfirmation.cshtml.cs file to open the backing class.

This is the ResendEMailConfirmationModel class.

// Areas -> Auth -> Pages -> ResendEMailConfirmation.cshtml.cs 

// namespaces 
using Microsoft.AspNetCore.Authorization;

using Microsoft.AspNetCore.Identity;

using Microsoft.AspNetCore.Mvc;

using Microsoft.AspNetCore.Mvc.RazorPages;

using Microsoft.AspNetCore.WebUtilities;

using System.ComponentModel.DataAnnotations;

using System.Text;

namespace MyRazorApp.Areas.Auth.Pages
{

  [AllowAnonymous]
  public class ResendEMailConfirmationModel : PageModel
  {

    // user id, i.e., email 
    [BindProperty]
    [Required]
    [DataType(DataType.EmailAddress)]
    public String? UserID { get; set; }

    // UserManager service 
    private readonly UserManager<IdentityUser> _um;

    // dependency injection 
    public ResendEMailConfirmationModel(UserManager<IdentityUser> um)
    {

      _um = um;

    }

    public async Task<IActionResult> OnPostAsync()
    {

      if (!ModelState.IsValid)
      {

        return Page();

      }

      IdentityUser user = await _um.FindByEmailAsync(UserID);

      // if user not registered, or bad entry 
      if (null == user)
      {

        ModelState.AddModelError(string.Empty, "EMail not found.");

        return Page();

      }

      // generate the token 
      var code = await _um.GenerateEmailConfirmationTokenAsync(user);

      // encode as base64 
      code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));

      // create the link and email or send by sms 
      /*
      String link = Url.Page(
          "/ConfirmAccount",
          null,
          new { area = "Auth", userID = userID, code = code },
          Request.Scheme);

      */

      // during testing - we use a test page 
      return RedirectToPage("EMailTestPage",
          new { userId = user.Id, code = code });

    }

  }

}

First we have the namespace directives.

The class has been marked as [AllowAnonymous] so that it is publically available.

Then we have UserID as the bind property for the email of the user.

Constructor based dependency injection has been used to obtain the UserManager service. This service is used to obtain the email confirmation token. We have cached it as a readonly member.

The OnPost method executes when the user submits and posts the form.

The FindByEmailAsync method is used to obtain the IdentityUser.

If the user cannot be found, then a suitable message is shown.

The confirmation token is obtained through the GenerateEmailConfirmationTokenAsync function.

Then it is encoded as a base64 string.

As you can see in the commented part, the link can now be generated by using the Url.Page function. In a real world application this link would be emailed at this point.

But since we are in a tutorial, we can redirect the user to an email test page and show the link there. This is the same thing that we did in the previous tutorial.

For completeness, we can have a look at the email test page. Come to the solution explorer and locate the email test page.


// Pages -> EMailTestPage.cshtml 

@page

@functions {

  public String? Link { get; set; }

  public void OnGet(String userID, String code)
  {
    Link = Url.Page(
                "/ConfirmAccount",
                null,
                new { area = "Auth", userID = userID, code = code },
                Request.Scheme);
  }
}

<h1>Test EMail</h1>

<p>
  NOTE: in real application this link is sent in an email to the user. 
  He has to click the link for email verification.
</p>

<h2>Please click to confirm your email</h2>

<a href="@(Link)">Click to Confirm</a>

Double click to open it. As you can see, the link is generated in the OnGet method, and displayed through an anchor tag.

Run the Project

Run the project and visit the login page. Click the ResendEMailConfirmation link. We are redirected to the resend email confirmation page. Type a registered email, and click the send button. That takes us to the test email page where we can confirm our account. In a real application there will be no test page. Instead of that the user would be emailed the link. Thanks!


This Blog Post/Article "(C# ASP.NET Core) Resending an Account Verification EMail in Identity based Authentication" by Parveen is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.