@model IEnumerable<AppUser>
ViewData["Title"] = "READ USER";
<h1 class="bg-info text-white">All Users</h1>
<a asp-action="Create" class="btn btn-secondary">Create a User</a>
<table class="table table-sm table-bordered">
<th>ID</th>
<th>Name</th>
<th>Email</th>
<th>Update</th>
@foreach (AppUser user in Model)
<td>@user.Id</td>
<td>@user.UserName</td>
<td>@user.Email</td>
<a class="btn btn-sm btn-primary" asp-action="Update" asp-route-id="@user.Id">
Update
</table>
Coming to the
Admin controller
, here we need to add a dependency of
IPasswordHasher
in the constructor. It is used to get the hashed value of the
user password
. This is because for security purpose ASP.NET Core Identity stores the User password in
Hashed value
instead of plain text. Therefore even if a hacker gains access to the database and finds this hashed value, he cannot login to a user acccount.
So, update the
AdminController.cs
as shown below:
using Microsoft.AspNetCore.Mvc;
using Identity.Models;
using Microsoft.AspNetCore.Identity;
namespace Identity.Controllers
public class AdminController : Controller
private UserManager<AppUser> userManager;
private IPasswordHasher<AppUser> passwordHasher;
public AdminController(UserManager<AppUser> usrMgr, IPasswordHasher<AppUser> passwordHash)
userManager = usrMgr;
passwordHasher = passwordHash;
// removed for brevity
Next, add the
Update action
to the
Admin controller
. The code is highlighted and given below:
using Microsoft.AspNetCore.Mvc;
using Identity.Models;
using Microsoft.AspNetCore.Identity;
namespace Identity.Controllers
public class AdminController : Controller
private UserManager<AppUser> userManager;
private IPasswordHasher<AppUser> passwordHasher;
public AdminController(UserManager<AppUser> usrMgr, IPasswordHasher<AppUser> passwordHash)
userManager = usrMgr;
passwordHasher = passwordHash;
// removed for brevity
public async Task<IActionResult> Update(string id)
AppUser user = await userManager.FindByIdAsync(id);
if (user != null)
return View(user);
return RedirectToAction("Index");
[HttpPost]
public async Task<IActionResult> Update(string id, string email, string password)
AppUser user = await userManager.FindByIdAsync(id);
if (user != null)
if (!string.IsNullOrEmpty(email))
user.Email = email;
ModelState.AddModelError("", "Email cannot be empty");
if (!string.IsNullOrEmpty(password))
user.PasswordHash = passwordHasher.HashPassword(user, password);
ModelState.AddModelError("", "Password cannot be empty");
if (!string.IsNullOrEmpty(email) && !string.IsNullOrEmpty(password))
IdentityResult result = await userManager.UpdateAsync(user);
if (result.Succeeded)
return RedirectToAction("Index");
Errors(result);
ModelState.AddModelError("", "User Not Found");
return View(user);
private void Errors(IdentityResult result)
foreach (IdentityError error in result.Errors)
ModelState.AddModelError("", error.Description);
Explanation
The
HTTP GET
version of the
Update Action
takes a string value called
id
. It will contains the Id value of the user registered in the Identity database. The
User’s record
is fetched from the Identity database using the
FindByIdAsync()
method of the
UserManager
class. The
FindByIdAsync()
method is provided with the Id of the Identity User as shown below.
AppUser user = await userManager.FindByIdAsync(id);
Once the User’s information is fetched, it is then send to the
Update View
as
model
.
The
HTTP POST
version of the
Update Action
is where we update the identity user’s record. This action is invoked when the user clicks the submit button on the update form given on the
Update View
.
First we fetch the User’s information in an
AppUser
object by using the
FindByIdAsync()
method:
AppUser user = await userManager.FindByIdAsync(id);
If the
AppUser
object is not null, we proceed by checking if the
new email and password
values are not empty. If they contain proper values then we update the
Email and PasswordHash property
values of the
AppUser
object to the new ones that are provided in the update form.
See the below code which does this work:
if (!string.IsNullOrEmpty(email))
user.Email = email;
ModelState.AddModelError("", "Email cannot be empty");
if (!string.IsNullOrEmpty(password))
user.PasswordHash = passwordHasher.HashPassword(user, password);
ModelState.AddModelError("", "Password cannot be empty");
Note that to
update password in Identity
we used the
HashPassword()
method to
generate password hash
of the password string that the user entered. This is done because Identity stores password in it’s
hashed representation
and not in the plain text.
user.PasswordHash = passwordHasher.HashPassword(user, password);
Finally, we update them using the
UpdateAsync
method. This method takes the
AppUser
object. The associated code is given below:
if (!string.IsNullOrEmpty(email) && !string.IsNullOrEmpty(password))
IdentityResult result = await userManager.UpdateAsync(user);
if (result.Succeeded)
return RedirectToAction("Index");
Errors(result);
}
In case, if the
UpdateAsync()
method does not completes successfully, then the method called
Errors()
is called to add the errors contained by
IdentityResult
object to the Model State. These errors will be shown on the browser. This code is:
void Errors(IdentityResult result)
foreach (IdentityError error in result.Errors)
ModelState.AddModelError("", error.Description);
}
Now, create the
Update.cshtml
razor view inside the
Views ➤ Admin
folder with the following code:
@model AppUser
ViewData["Title"] = "UPDATE USER";
<h1 class="bg-info text-white">Update User</h1>
<a asp-action="Index" class="btn btn-secondary">Back</a>
<div asp-validation-summary="All" class="text-danger"></div>
<form asp-action="Update" method="post">
<div class="form-group">
<label asp-for="Id"></label>
<input asp-for="Id" class="form-control" disabled />
<div class="form-group">
<label asp-for="Email"></label>
<input asp-for="Email" class="form-control" />
<div class="form-group">
<label for="password">Password</label>
<input name="password" class="form-control" />
<button type="submit" class="btn btn-primary">Save</button>
</form>
Test the update feature by re-visiting the
Index action of Admin Controller
having the URL –
https://localhost:7263/Admin
. There click the
Update button
which will take you to the update page. Add new Email and password and click the save button. This will update the User’s record stored in the Identity database.
The below images illustrates the Update feature:
Delete Users in Identity
The final CRUD operation is the
Delete users from Identity database
. It will be done by the
Delete Action
method of the
Admin Controller
. The code of the
Delete Action
method is given below.
using Microsoft.AspNetCore.Mvc;
using Identity.Models;
using Microsoft.AspNetCore.Identity;
namespace Identity.Controllers
public class AdminController : Controller
private UserManager<AppUser> userManager;
private IPasswordHasher<AppUser> passwordHasher;
public AdminController(UserManager<AppUser> usrMgr, IPasswordHasher<AppUser> passwordHash)
userManager = usrMgr;
passwordHasher = passwordHash;
// removed for brevity
[HttpPost]
public async Task<IActionResult> Delete(string id)
AppUser user = await userManager.FindByIdAsync(id);
if (user != null)
IdentityResult result = await userManager.DeleteAsync(user);
if (result.Succeeded)
return RedirectToAction("Index");
Errors(result);
ModelState.AddModelError("", "User Not Found");
return View("Index", userManager.Users);
This
ASP.NET Core Action method
receives the User Id and it fetches the user’s Identity record using the
FindByIdAsync()
method. We get the corresponding User in an
AppUser
object. Then we use the
DeleteAsync
method to delete the Identity user from the database. The below code does the delete work:
IdentityResult result = await userManager.DeleteAsync(user);
If the delete operation completes successfully then user is redirected to the
Index Action
method else the
Errors()
function is called to show the errors to the user.
The delete button needs to be added to the HTML table of the
Index View
. This is shown in the highlighted code given below.
@model IEnumerable<AppUser>
ViewData["Title"] = "READ USER";
<h1 class="bg-info text-white">All Users</h1>
<a asp-action="Create" class="btn btn-secondary">Create a User</a>
<table class="table table-sm table-bordered">
<th>ID</th>
<th>Name</th>
<th>Email</th>
<th>Update</th>
<th>Delete</th>
@foreach (AppUser user in Model)
<td>@user.Id</td>
<td>@user.UserName</td>
<td>@user.Email</td>
<a class="btn btn-sm btn-primary" asp-action="Update" asp-route-id="@user.Id">
Update
<form asp-action="Delete" asp-route-id="@user.Id" method="post">
<button type="submit" class="btn btn-sm btn-danger">
Delete
</button>
</form>
</table>