Register New User Using ASP.NET Core Identity

Register New User Using ASP.NET Core Identity

In this article, I will discuss How to Register a New User Using ASP.NET Core Identity. Please read our previous article discussing UserManager, SignInManager, and RoleManager Classes in ASP.NET Core Identity.

Register New User Using ASP.NET Core Identity

We need to create a form for new user registration that looks like the one shown below. The form typically contains fields like Email, Password, and Confirmation Password to register a new user.

Register New User Using ASP.NET Core Identity

Currently, we are using these three fields to register a new user. As we progress in this course, I will show you how to add more fields like First Name, Last Name, and Date of Birth. But for now, we are using these three fields.

Our requirement is that when the user provides the Email, Password, and Confirm Password and clicks on the Register button, we need to add the user to the AspNetUsers Identity database table. While adding the user, we also need to check the validation, such as the Email Address should be unique, the Email must be a valid email, and the provided password should pass the password policy that the ASP.NET Core Identity Framework sets. Let us proceed and see how we can implement this step by step using ASP.NET Core Identity:

Creating the RegisterViewModel Class

Create a class file named RegisterViewModel.cs in the Models folder, and then copy and paste the following code. We will use this RegisterViewModel Class as the model for the Register view. In the following class, we have used several data annotation attributes for the Model Validation.

using System.ComponentModel.DataAnnotations;
namespace ASPNETCoreIdentityDemo.Models
{
    public class RegisterViewModel
    {
        [Required]
        [EmailAddress]
        public string Email { get; set; }

        [Required]
        [DataType(DataType.Password)]
        public string Password { get; set; }

        [DataType(DataType.Password)]
        [Display(Name = "Confirm password")]
        [Compare("Password", ErrorMessage = "Password and confirmation password do not match.")]
        public string ConfirmPassword { get; set; }
    }
}
AccountController

Next, create an empty MVC controller named AccountController within the Controllers folder and copy and paste the following code. This AccountController will handle all the user account-related operations. At the moment, we have the Register action method, which is decorated with the HttpGer attribute, and we can reach this action method by issuing a GET request to URL: /account/register. In the later part of this article, I will add the post version of the Register action method, where we will use the ASP.NET Core Identity to add the new user to the database.

using Microsoft.AspNetCore.Mvc;

namespace ASPNETCoreIdentityDemo.Controllers
{
    public class AccountController : Controller
    {
        [HttpGet]
        public IActionResult Register()
        {
            return View();
        }
    }
}
Register View

Create a view named Register.cshtml and place this view inside the Views/Account folder. The model for this view is RegisterViewModel. Once you create the Register.cshtml view, copy and paste the following code. This is the view using which we can register a new user in our application.

@model RegisterViewModel

@{
    ViewBag.Title = "User Registration";
}

<h1>User Registration</h1>

<div class="row">
    <div class="col-md-12">
        <form method="post">
            <div asp-validation-summary="All" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Email"></label>
                <input asp-for="Email" class="form-control" />
                <span asp-validation-for="Email" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Password"></label>
                <input asp-for="Password" class="form-control" />
                <span asp-validation-for="Password" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="ConfirmPassword"></label>
                <input asp-for="ConfirmPassword" class="form-control" />
                <span asp-validation-for="ConfirmPassword" class="text-danger"></span>
            </div>
            <button type="submit" class="btn btn-primary">Register</button>
        </form>
    </div>
</div>
Register Link in the Layout View

We want to include a link for the register view in the navigation menus. So, open the Layout.cshtml file and copy and paste the following code. This will add a navigation menu item named Register. Clicking on this Register link will open the Register view.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - ASPNETCoreIdentityDemo</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
    <link rel="stylesheet" href="~/ASPNETCoreIdentityDemo.styles.css" asp-append-version="true" />
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container-fluid">
                <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">ASPNETCoreIdentityDemo</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
                        </li>
                    </ul>
                    <ul class="navbar-nav ml-auto">
                        <li class="nav-item">
                            <a class="nav-link" asp-controller="account" asp-action="register">
                                Register
                            </a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2023 - ASPNETCoreIdentityDemo - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
        </div>
    </footer>
    <script src="~/lib/jquery/dist/jquery.min.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>
    @await RenderSectionAsync("Scripts", required: false)
</body>
</html>

With the above changes in place, if you run the application, then it will display the register view. Now, let us proceed and see how to provide the functionality to add the user to the ASP.NET Core Identity database AspNetUsers table.

How do you register and sign in as a new user using an ASP.NET Core Identity?

As we already discussed, ASP.NET Core Identity provided the UserManager class for database CRUD operations related to users, such as creating a new user, updating an existing user, deleting a user, and fetching the user details. Similarly, ASP.NET Core Identity provided the SignInManager class to perform the Sign-in or Sign-out functionalities.

Creating New User in ASP.NET Core Identity

We need to use the following CreateAsync method of the UserManager<TUser> class to create a new user in the AspNetUsers table:

Task<IdentityResult> CreateAsync(TUser user, string password);

Parameters
  • TUser user: This is an instance of the IdentityUser class that contains user information. The TUser type is typically a class that derives from IdentityUser, but you can also directly use the IdentityUser class. This parameter represents the user you want to create, and it should contain the necessary user information like username, email, etc.
  • string password: This is the password for the new user. ASP.NET Core Identity will handle the hashing and storage of this password securely.
Return Type
  • Task<IdentityResult>: The method returns Task<IdentityResult>. The IdentityResult result indicates whether the user creation was successful or not. It contains details about the success of the operation or a list of errors if the operation failed (for example, if the username is already taken, if the password doesn’t meet complexity requirements, or if the email is not valid, etc.).
Sign-in a New User After Successful Registration:

So, our requirement is that once the user is successfully registered, i.e., added to the AspNetUsers identity table, the user needs to be sign in automatically. For this purpose, we need to use the SignInAsync method of the SignInManager class. The SignInAsync method is primarily used when we want to sign in a user without requiring them to provide their password.

This is useful in scenarios like user registration, where you want to sign in the user immediately after they have registered, or in external login flows, where the user is authenticated through an external provider. The following is the signature:

Task SignInAsync(TUser user, bool isPersistent, string authenticationMethod = null)

Parameters
  • TUser user: The user object. This is typically an instance of the IdentityUser class or a class that extends it.
  • bool isPersistent: If set to true, the sign-in cookie will be persistent across browser sessions. If false, the cookie will be session-based and disappear when the browser is closed.
  • string authenticationMethod (Optional): This parameter is optional and can be used to specify the authentication method used. For example, we need to specify “Password” or “TwoFactor”.

So, let us use the above two methods to register a user, and if the user registers successfully, then immediately sign in the user. Please modify the Account Controller as follows to implement the user register and sign-in functionality in the Register Post action method. The following code is self-explained, so please go through the comment lines for a better understanding.

using ASPNETCoreIdentityDemo.Models;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;

namespace ASPNETCoreIdentityDemo.Controllers
{
    public class AccountController : Controller
    {
        //userManager will hold the UserManager instance
        private readonly UserManager<IdentityUser> userManager;

        //signInManager will hold the SignInManager instance
        private readonly SignInManager<IdentityUser> signInManager;

        //Both UserManager and SignInManager services are injected into the AccountController
        //using constructor injection
        public AccountController(UserManager<IdentityUser> userManager,
            SignInManager<IdentityUser> signInManager)
        {
            this.userManager = userManager;
            this.signInManager = signInManager;
        }

        [HttpGet]
        public IActionResult Register()
        {
            return View();
        }

        [HttpPost]
        public async Task<IActionResult> Register(RegisterViewModel model)
        {
            if (ModelState.IsValid)
            {
                // Copy data from RegisterViewModel to IdentityUser
                var user = new IdentityUser
                {
                    UserName = model.Email,
                    Email = model.Email
                };

                // Store user data in AspNetUsers database table
                var result = await userManager.CreateAsync(user, model.Password);

                // If user is successfully created, sign-in the user using
                // SignInManager and redirect to index action of HomeController
                if (result.Succeeded)
                {
                    await signInManager.SignInAsync(user, isPersistent: false);
                    return RedirectToAction("index", "home");
                }

                // If there are any errors, add them to the ModelState object
                // which will be displayed by the validation summary tag helper
                foreach (var error in result.Errors)
                {
                    ModelState.AddModelError(string.Empty, error.Description);
                }
            }

            return View(model);
        }
    }
}
Explanation of the above Code:
  • In the above code, the UserManager and SignInManager services are injected into the AccountController using constructor injection. Both services accept a generic parameter. 
  • At the moment, we are using the built-in IdentityUser class as the argument for the generic parameter. In our upcoming articles, we will see how we can create our custom Identity User class with additional data and then plug in that custom Identity User class as an argument for the generic parameter instead of the built-in IdentityUser class.

Now, if you run the application and provide a valid email address and password, the user account should be created in the AspNetUsers table in the underlying SQL server database. So, run the application and provide the details as follows:

How to Register a New User Using ASP.NET Core Identity

If you are not getting any errors, please check the AspNetUsers database table, and you should see the following record.

How to Add a New User Using ASP.NET Core Identity

Trying to add a New User with an Existing Email Id:

If you try to add a New User with an Existing Email ID, then it will not allow it, and it will give you the following error:

Add a New User Using ASP.NET Core Identity

Trying to add a New User with a Simple Password:

Let us try to add a new user with password 123456 and see what happens, as shown in the below image:

ASP.NET Core Identity New User Registration

As you can see in the above image, the following validations are provided in the password column:

  • Passwords must be at least 6 characters.
  • Passwords must have at least one non-alphanumeric character.
  • Passwords must have at least one lowercase (‘a’-‘z’).
  • Passwords must have at least one uppercase (‘A’-‘Z’).

In our upcoming article, I will show you how to provide your own password policy rather than using this default one. But, the problem with this example is it does not show whether the user is logged in or logged out. So, in the next article, I will show you how to implement the Login and Logout functionality.

In the next article, I will discuss Login and Logout in ASP.NET Core Identity. In this article, I try to explain How to Register a New User Using ASP.NET Core Identity. I hope you enjoy this Register New User Using ASP.NET Core Identity article.

Registration Open For New Online Training

Enhance Your Professional Journey with Our Upcoming Live Session. For complete information on Registration, Course Details, Syllabus, and to get the Zoom Credentials to attend the free live Demo Sessions, please click on the below links.

Leave a Reply

Your email address will not be published. Required fields are marked *