Click here to Skip to main content
15,884,986 members
Articles / Web Development / HTML
Tip/Trick

ASP:NET MVC 5 Confirm Registration Email

Rate me:
Please Sign up or sign in to vote.
4.87/5 (26 votes)
6 May 2016CPOL3 min read 242.7K   8.7K   47   41
How to check Email address during user registration with ASP.NET MVC 5

Introduction

With the new ASP.NET Identity, our applications are increasingly linked to the integration with social networks.

In the face of these additions, the new membership by default with ASP.NET MVC 4/5, is (intentionally) very "lean" and free of many features that are used to manage custom accounts provided on his application.

One of the features "missing" is the ability to send an Email confirmation in respect of the registration of a user, to verify that the email address exists. Figure 1 represents the login form with Email Field.

Registration

Using the Code

Below, I will explain in a step by step manner how to create a simple registration "custom" I have to send a confirmation email to the registration site.

Model User

Creating an application like ASP.NET MVC by default in the Models folder, we find the ApplicationUser class, this class contains the definition of the model of our User.

The first step is to add the following properties to our class:

  • Email: E-mail address of our user
  • ConfirmedEmail: A Boolean value that indicates the Email address after user's confirmation.
C#
public class ApplicationUser : IdentityUser
{
   public string Email{ get; set; }
   public bool ConfirmedEmail { get; set; }
}  
Registration ViewModel

Once you add the Email property to our model, we should modify the view model used in the user registration adding the Email field:

C#
public class RegisterViewModel
 {
     [Required]
     [Display(Name = "User name")]
     public string UserName { get; set; }

     [Required]
     [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
     [DataType(DataType.Password)]
     [Display(Name = "Password")]
     public string Password { get; set; }

     [DataType(DataType.Password)]
     [Display(Name = "Confirm password")]
     [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
     public string ConfirmPassword { get; set; }
     [Required]
     [EmailAddress]
     [Display(Name = "E-mail")]
     public string Email { get; set; }

 }

Our field during the registration process will be mandatory ([Required]) and Type Email ([EmailAddress]), so that the front end will be activated client side scripts to check the presence of the data and the validity of the form (Email Address).

Registration Form

After changing the Register ViewModel, we can update the View User's registration:

C++
 @{
    ViewBag.Title = "Register";
}

<h2>@ViewBag.Title.</h2>

@using (Html.BeginForm("Register", "Account",
FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
    @Html.AntiForgeryToken()
    <h4>Create a new account.</h4>
    <hr />
    @Html.ValidationSummary()
    <div class="form-group">
        @Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.UserName, new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.PasswordFor(m => m.Password, new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" })
        </div>
    </div>
     <div class="form-group">
        @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.Email, new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" class="btn btn-default" value="Register" />
        </div>
    </div>
}

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

Action ConfirmEmail and Register

After changing the interface (View), we can finally add a new Action ConfirmEmail and change the Action Register of our controller (AccountController) used for registration, adding sending an e-mail address provided during registration:

C#
  // GET: /Account/ConfirmEmail
  [AllowAnonymous]
  public async Task<ActionResult> ConfirmEmail(string Token, string Email)
   {
     ApplicationUser user = this.UserManager.FindById(Token);
     if (user != null)
        {
         if (user.Email == Email)
            {
             user.ConfirmedEmail = true;
             await UserManager.UpdateAsync(user);
             await SignInAsync(user, isPersistent: false);
             return RedirectToAction("Index", "Home", new { ConfirmedEmail = user.Email });            }
            else
            {
             return RedirectToAction("Confirm", "Account", new { Email = user.Email });
            }
        }
        else
        {
          return RedirectToAction("Confirm", "Account", new { Email = "" });
        }
  }

// POST: /Account/Register
  [HttpPost]
  [AllowAnonymous]
  [ValidateAntiForgeryToken]
  public async Task<ActionResult> Register(RegisterViewModel model)
  {
   if (ModelState.IsValid)
    {
      var user = new ApplicationUser() { UserName = model.UserName };
      user.Email = model.Email;
      user.ConfirmedEmail = false;
      var result = await UserManager.CreateAsync(user, model.Password);
      if (result.Succeeded)
       {
         System.Net.Mail.MailMessage m = new System.Net.Mail.MailMessage(
         new System.Net.Mail.MailAddress("sender@mydomain.com", "Web Registration"),
         new System.Net.Mail.MailAddress(user.Email));
             m.Subject = "Email confirmation";
             m.Body = string.Format("Dear {0}
             <BR/>Thank you for your registration, please click on the
             below link to complete your registration: <a href=\"{1}\"
             title=\"User Email Confirm\">{1}</a>",
             user.UserName, Url.Action("ConfirmEmail", "Account",
             new { Token = user.Id, Email = user.Email }, Request.Url.Scheme));
           m.IsBodyHtml = true;
     System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient("smtp.mydomain.com");
     smtp.Credentials = new System.Net.NetworkCredential("sender@mydomain.com", "password");
smtp.ServerCertificateValidationCallback = () => true; //Solution for client certificate error
C#
        smtp.EnableSsl = true;
        smtp.Send(m);
        return RedirectToAction("Confirm", "Account", new { Email = user.Email });
      }
      else
      {
        AddErrors(result);
      }
    }
  // If we got this far, something failed, redisplay form
    return View(model);
}  

Since sample code I leave to you the change for the management of localized strings for the parameters and sending the mail (the example uses a mydomain.com account, but you can use your email address).

Action / Confirm View

As you can see from the code, once you register a new user, a mail is sent and, unlike the default recording, is called the action "Confirm" that is used to display video in the notification of sending mail registration confirmation the address indicated on the registration form:

C#
 [AllowAnonymous]
public ActionResult Confirm(string Email)
{
  ViewBag.Email = Email;return View();
} 

Finally add the Confirm View:

HTML
@{
    ViewBag.Title = "Confirm Email Address Sent";
}
<h2>@ViewBag.Title.</h2>

<div class="row">
    <div class="col-md-8">
        Please check your Email Inbox, a confirm Email is Sent to @ViewBag.Email
        </div>
 </div>  

Once you have applied the changes described in the previous steps, you can compile the web application and try a new user's registration. If everything is correct, there will come an Email to the address given in filling in the registration form, which contains a useful link for the confirmation of the email, for simplicity inside the link will be passed to the user's unique identifier and the 'e-mailreference. By clicking on the link contained within Mail, will be called the Action "ConfirmEmail" which, once checked the input data, will mark as confirmed the email address of the user.

User Login

We can also change the flow of the application login to prevent access of a not yet "confirmed" user, always changing our controller:

C#
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
      var user = await UserManager.FindAsync(model.UserName, model.Password);
      if (user != null)
      {
        if (user.ConfirmedEmail == true)
         {
           await SignInAsync(user, model.RememberMe); return RedirectToLocal(returnUrl);
         }
         else
         {
           ModelState.AddModelError("", "Confirm Email Address.");
         }
      }
      else
      {
        ModelState.AddModelError("", "Invalid username or password.");
      }
   }
   // If we got this far, something failed, redisplay form
   return View(model);
}

It simply checks the value of the property User's ConfirmedEmail before logging on.

I hope the guide has been useful to you.

P.S. Remember to change the parameters for sending mail!

History

  • March 2014: First release

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Italy Italy
I am an Italian developer specialized on ASP.NET web applications.
I consider myself a lucky person because my work coincides with my passion: Develop code!
I began to develop code from the age of about ten years with the infamous Commodore 64.
My turning point was the advent of the internet since 1995 and I started to develop websites first static and then dynamic (ASP) before moving to. NET platform since then ... I do not have more 'stopped!

Comments and Discussions

 
QuestionError: System.FormatException Pin
emanuel velasquez4-Sep-19 6:42
emanuel velasquez4-Sep-19 6:42 
QuestionTwo unanswered Questions Pin
Member 1412397229-Jan-19 4:27
Member 1412397229-Jan-19 4:27 
QuestionMy Project Doesnt have a ConfirmEmail controller and view Pin
Member 1375602031-Mar-18 2:08
Member 1375602031-Mar-18 2:08 
QuestionA network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connection Pin
Member 1265673126-Apr-17 4:29
Member 1265673126-Apr-17 4:29 
QuestionA network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connection Pin
Member 1265673126-Apr-17 4:29
Member 1265673126-Apr-17 4:29 
Questionhost failed to respond Pin
Member 126464436-Aug-16 1:23
Member 126464436-Aug-16 1:23 
QuestionThe remote certificate is invalid according to the validation procedure. Pin
Member 1242911911-Apr-16 1:56
Member 1242911911-Apr-16 1:56 
QuestionThe tags in the mail body isnt getting used as tags Pin
Member 1199819815-Mar-16 23:12
Member 1199819815-Mar-16 23:12 
AnswerRe: The tags in the mail body isnt getting used as tags Pin
#realJSOP20-Mar-16 11:23
mve#realJSOP20-Mar-16 11:23 
QuestionThe remote certificate is invalid according to the validation procedure. Pin
Member 1199819815-Mar-16 4:17
Member 1199819815-Mar-16 4:17 
I get "The remote certificate is invalid according to the validation procedure. and error on
C#
smtp.Send(m);
what is the problem? I found one solution is to hack the credentials but that is stupid since this needs to be in production.
AnswerRe: The remote certificate is invalid according to the validation procedure. Pin
#realJSOP20-Mar-16 11:30
mve#realJSOP20-Mar-16 11:30 
QuestionConfirm Confirmation Pin
Nehllah17-Nov-15 21:33
Nehllah17-Nov-15 21:33 
AnswerRe: Confirm Confirmation Pin
#realJSOP20-Mar-16 11:24
mve#realJSOP20-Mar-16 11:24 
GeneralRe: Confirm Confirmation Pin
Member 138136431-Apr-19 9:35
Member 138136431-Apr-19 9:35 
QuestionCode First Migration Pin
Nehllah17-Nov-15 3:17
Nehllah17-Nov-15 3:17 
QuestionError Pin
Member 1199362921-Sep-15 2:35
Member 1199362921-Sep-15 2:35 
GeneralThank you, and well done. Pin
jasonalls4-Sep-15 4:13
professionaljasonalls4-Sep-15 4:13 
QuestionIt Showing Errors thta remote name could not be resolved Pin
@shok kumar mishra20-Jul-15 21:21
@shok kumar mishra20-Jul-15 21:21 
AnswerRe: It Showing Errors thta remote name could not be resolved Pin
congiuluc23-Jul-15 4:34
congiuluc23-Jul-15 4:34 
Questionwhy it said error when sending mail? Pin
Member 1171626727-Jun-15 4:17
Member 1171626727-Jun-15 4:17 
AnswerRe: why it said error when sending mail? Pin
congiuluc23-Jul-15 4:35
congiuluc23-Jul-15 4:35 
QuestionFIXED: The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.5.1 Authentication Required? Pin
Emmanuel Reyme, Jr19-Jul-14 11:46
Emmanuel Reyme, Jr19-Jul-14 11:46 
AnswerRe: FIXED: The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.5.1 Authentication Required? Pin
congiuluc21-Jul-14 3:35
congiuluc21-Jul-14 3:35 
QuestionI have a problem with "var result = await UserManager.CreateAsync(user, model.Password);" Pin
Member 109250674-Jul-14 6:27
Member 109250674-Jul-14 6:27 
AnswerRe: I have a problem with "var result = await UserManager.CreateAsync(user, model.Password);" Pin
congiuluc4-Jul-14 21:58
congiuluc4-Jul-14 21:58 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.