Need to Know RoleManager Asp.Net Core 2019

Previous article links :- https://sagarjaybhay.com/asp-net-core/

RoleManager In Asp.Net Core

For this, we have a RoleManager class to

  1. Create
  2. Read
  3. Update
  4. Delete

The roles and we use this conjunction with userManager class and for this, we have to pass IdentityUser object. For saving role identity created one table for it in a database which is the AspNetRoles table.

First, we create a view model for creating role and for that we create rolename field in our model.

public class RoleViewModel
    {
        [Required]
        public string RoleName { get; set; }
    }

After this, we create a view for that and in this view, we use the above-created view model.

@model RoleViewModel
@{
    ViewData["Title"] = "CreateRoles";
}

<h1>CreateRoles</h1>

<div class="row">
    <div class="col-md-4">
        <form asp-action="CreateRoles" method="post">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="RoleName" class="control-label"></label>
                <input asp-for="RoleName" class="form-control" />
                <span asp-validation-for="RoleName" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

After this we have created onecontroller in that we have method for register user.

  public class RegistrationVIewModel
    {

        [Required]
        [EmailAddress]
        [Remote(controller:"Account",action: "IsUsedEmailID")]
        [CustomValidator(allowedDomain:"gmail.com",ErrorMessage = "Email Domain Must Be gmail.com")]
        public string Email { get; set; }

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


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

        public string City { get; set; }
        public string Zip { get; set; }
    }

Roles in asp.net core 2019
Roles in asp.net core 2019

How to create, update, delete roles in asp.net core?

First, we have created a list of all roles present in our table which is AspNetRole.

Roles created in asp.net core
Roles created in asp.net core

Create Role In Asp.Net Core

In this, we have created action in our controller which is CreateRole in that we have added 2 methods for CreateRole. One is httpget to get only Html and another post which is for posting the roles data to a database.

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

For this below is the html code for this

@model RoleViewModel
@{
    ViewData["Title"] = "CreateRoles";
}

<h1>CreateRoles</h1>

<div class="row">
    <div class="col-md-4">
        <form asp-action="CreateRoles" method="post">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="RoleName" class="control-label"></label>
                <input asp-for="RoleName" class="form-control" />
                <span asp-validation-for="RoleName" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

In which we have show create role html page and page looks like below

Create Role Ui in asp.net core
Create Role Ui in asp.net core

For post method

[HttpPost]
        public async Task<IActionResult> CreateRoles(RoleViewModel roleView)
        {
            if (ModelState.IsValid)
            {
                IdentityRole role=new IdentityRole()
                {
                    Name = roleView.RoleName
                };

               IdentityResult result=await this.rolesManager.CreateAsync(role);

               if (result.Succeeded)
                   return RedirectToAction("ListOfRoles", "Rolemanag");

               foreach (var identityErrorLE in result.Errors)
               {
                   ModelState.AddModelError("",identityErrorLE.Description);
               }
            }

            return View(roleView);
        }

Method this is code in controller.

Display All Roles in Asp.Net Core

In our constructor, we injected RoleManager by using dependency injection below is the code for that

  public RoleManager<IdentityRole> rolesManager { get; set; }
        public RolemanagController(RoleManager<IdentityRole> rolesManager,UserManager<ExtendedIdentityUser> userManager)
        {
            _userManager = userManager;
            this.rolesManager = rolesManager;
        }

So by using this object, we are able to get all roles present currently. For that, we have created one method in our controller below is the method.

public IActionResult ListOfRoles()
        {
            var list = this.rolesManager.Roles;
            return View(list);

        }

and html code for this is

@model IQueryable<IdentityRole>;
@{
    ViewData["Title"] = "ListOfRoles";
}

<h1>All Roles</h1>

@if (Model.Any())
{
    foreach (var role in Model)
    {
        <div class="card">
            <div class="card-header">
                @role.Id   
            </div>
            <div class="card-body">
                
                <h4 class="card-title">
                    @role.Name
                </h4>
            </div>
            <div class="card-footer">
                <a class="btn btn-info" asp-action="EditRole" asp-controller="Rolemanag" asp-route-id="@role.Id">Edit</a>
                <a class="btn btn-danger" asp-action="" asp-controller="">Delete</a>
            </div>

        </div>


    }
    

}
else
{
    <div class="card">
        <div class="card-header">
            No Roles Found In Table
        </div>
        
        <div class="card-body">
            <a class="btn btn-info" asp-action="CreateRoles" asp-controller="Rolemanag">Create Role</a>
        </div>
    </div>
}

Below is the output of that Html code

All Roles in Asp.net Core
All Roles in Asp.net Core

In this, we are giving the functionality of the Edit and Delete role.

Edit Role in asp.net core

As you can see In AspNetRole table contains a name, normalized name, id and concurrency stamp. By using the edit role you can edit the name of a role. For edit role, we required ID which is auto-generated and we pass this id to our function and get a role from this.

Also for edit role, we created 2 action methods one for HttpGet and another for HttpPost and below is httpget method for EditRole which sends us Html

  [HttpGet]
        public async Task<IActionResult> EditRole(string id)
        {
            var role =await this.rolesManager.FindByIdAsync(id);
            if (role == null)
            {
                ViewBag.ErrorMessages = $"Role of given id {id} is not found.";
                return View("NotFound");
            }
            else
            {
                var model=new EditRoleViewModel()
                {
                    RoleName = role.Name,
                    Id =(role.Id),
                    
                };

                foreach (var users in _userManager.Users)
                {
                    if (await _userManager.IsInRoleAsync(users, role.Name))
                    {
                        model.Users.Add(users.UserName);
                    }
                    
                }

                return View(model);
            }

        }

Which and Html for this is like below

@model EditRoleViewModel
@{
    ViewData["Title"] = "EditRole";
}

<h1>Edit Role</h1>


<form asp-action="EditRole" method="post">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    <div class="form-group">
        <label asp-for="Id" class="control-label"></label>
        <input asp-for="Id" class="form-control" disabled="disabled" />
        <span asp-validation-for="Id" class="text-danger"></span>
    </div>
    <div class="form-group">
        <label asp-for="RoleName" class="control-label"></label>
        <input asp-for="RoleName" class="form-control" />
        <span asp-validation-for="RoleName" class="text-danger"></span>
    </div>
    
    <div class="form-group">
        <button type="submit" class="btn btn-primary"> update</button>
        <a type="submit" value="Cancel" class="btn btn-primary" asp-action="ListOfRoles" asp-controller="Rolemanag">Cancel</a>
    </div>
    
    
    
    
    <div class="card">
        
        <div class="card-header">
            <h2 class="card-title">User Name </h2>
        </div>
        <div class="card-body">
            
            @if (Model?.Users?.Any()!=null)
            {
                foreach (var user in Model.Users)
                {
                    <h5>@user</h5>
                }

            }
            else
            {
                <h3 class="text-danger" >No matching user found with this role</h3>
            }
        </div>
    </div>

</form>

Html for edit view we created one view model for that which is shown below

public class EditRoleViewModel
    {

        public string Id { get; set; }

        [Required(ErrorMessage = "Role Name Is Required.")]
        public string RoleName { get; set; }

        public List<string> Users { get; set; }
    }

And we use this in our view.

Edit Role in Asp.net core
Edit Role in Asp.net core

In this, we pass Id as a parameter and by that id, we retrieve the role. Then if we change the name we can update this.

Update Role For Users

  1. In identity, framework Users are stored in the AspNetUsers table
  2. Roles are stored in AspNetRoles
  3. We have these 2 tables i.e AspNetUsers and AspNetRoles have many to many relationships between table.
  4. We have another table AspNetUserRoles which is inbuilt and have 2 columns only UserId and RoleId and these both columns are foreign keys of AspNetUsers nad AspNetRoles.

First, we have a list of all roles which is shown below

All Saved Roles In asp.net core
All Saved Roles In asp.net core

When we click on Edit role we see below result

Edit Roles New In asp.net core
Edit Roles New In asp.net core

For edit, role post-action below is the method when we click on the Update button.

[HttpPost]
        public async Task<IActionResult> EditRole(EditRoleViewModel model)
        {
            var role = await this.rolesManager.FindByIdAsync(model.Id);
            if (role == null)
            {
                ViewBag.ErrorMessages = $"Role of given id {model.Id} is not found.";
                return View("NotFound");
            }
            else
            {
                role.Name = model.RoleName;
                var res=await this.rolesManager.UpdateAsync(role);
                if (res.Succeeded)
                {
                    return RedirectToAction("ListOfRoles", "Rolemanag");
                }

                foreach (var erros in res.Errors)
                {
                    ModelState.AddModelError("",erros.Description);
                }
            }
            return View(model);
        }

And View of this is below

@model EditRoleViewModel
@{
    ViewData["Title"] = "EditRole";
}

<h1>Edit Role</h1>


<form asp-action="EditRole" method="post">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    <div class="form-group">
        <label asp-for="Id" class="control-label"></label>
        <input asp-for="Id" class="form-control" disabled="disabled" />
        <span asp-validation-for="Id" class="text-danger"></span>
    </div>
    <div class="form-group">
        <label asp-for="RoleName" class="control-label"></label>
        <input asp-for="RoleName" class="form-control" />
        <span asp-validation-for="RoleName" class="text-danger"></span>
    </div>
    
    <div class="form-group">
        <button type="submit" class="btn btn-primary"> update</button>
        <a type="submit" value="Cancel" class="btn btn-primary" asp-action="ListOfRoles" asp-controller="Rolemanag">Cancel</a>
    </div>
    
    
    
    
    <div class="card">

        <div class="card-header">
            <h2 class="card-title">User Name </h2>
        </div>

        <div class="card-body">
            @if (Model?.Users?.Any() != null)
            {
                foreach (var user in Model.Users)
                {
                    <h5>@user</h5>


                }

            }
            else
            {
                <h3 class="text-danger">No matching user found with this role</h3>
            }
        </div>
        <div class="card-footer">
            <a  type="submit" class="btn btn-primary" asp-action="EditUsersInRoles" asp-controller="Rolemanag" asp-route-RoleId="@Model.Id"> Add / Remove Users</a>
        </div>

    </div>

</form>

Complete controller code

using System;
using System.Collections.Generic;
using LearnAspCore.ViewModel;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using LearnAspCore.Models;
using Microsoft.AspNetCore.Identity.UI.V3.Pages.Internal.Account;

namespace LearnAspCore.Controllers
{
    public class RolemanagController : Controller
    {
        private readonly UserManager<ExtendedIdentityUser> _userManager;
        public RoleManager<IdentityRole> rolesManager { get; set; }
        public RolemanagController(RoleManager<IdentityRole> rolesManager,UserManager<ExtendedIdentityUser> userManager)
        {
            _userManager = userManager;
            this.rolesManager = rolesManager;
        }

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

        [HttpPost]
        public async Task<IActionResult> CreateRoles(RoleViewModel roleView)
        {
            if (ModelState.IsValid)
            {
                IdentityRole role=new IdentityRole()
                {
                    Name = roleView.RoleName
                };

               IdentityResult result=await this.rolesManager.CreateAsync(role);

               if (result.Succeeded)
                   return RedirectToAction("ListOfRoles", "Rolemanag");

               foreach (var identityErrorLE in result.Errors)
               {
                   ModelState.AddModelError("",identityErrorLE.Description);
               }
            }

            return View(roleView);
        }

        public IActionResult ListOfRoles()
        {
            var list = this.rolesManager.Roles;
            return View(list);

        }

        [HttpGet]
        public async Task<IActionResult> EditRole(string id)
        {
            var role =await this.rolesManager.FindByIdAsync(id);
            if (role == null)
            {
                ViewBag.ErrorMessages = $"Role of given id {id} is not found.";
                return View("NotFound");
            }
            else
            {
                var model=new EditRoleViewModel()
                {
                    RoleName = role.Name,
                    Id =(role.Id),
                    
                };

                foreach (var users in _userManager.Users)
                {
                  //  model.Users=new List<string>();
                    if (await _userManager.IsInRoleAsync(users, role.Name))
                    {
                        model.Users.Add(users.UserName);
                    }
                    
                }

                return View(model);
            }

        }

        [HttpPost]
        public async Task<IActionResult> EditRole(EditRoleViewModel model)
        {
            var role = await this.rolesManager.FindByIdAsync(model.Id);
            if (role == null)
            {
                ViewBag.ErrorMessages = $"Role of given id {model.Id} is not found.";
                return View("NotFound");
            }
            else
            {
                role.Name = model.RoleName;
                var res=await this.rolesManager.UpdateAsync(role);
                if (res.Succeeded)
                {
                    return RedirectToAction("ListOfRoles", "Rolemanag");
                }

                foreach (var erros in res.Errors)
                {
                    ModelState.AddModelError("",erros.Description);
                }
            }
            return View(model);
        }

        [HttpGet]
        public async Task<IActionResult> EditUsersInRoles(string RoleId)
        {

            ViewBag.RoleId = RoleId;

            var role = await rolesManager.FindByIdAsync(RoleId);
            if (role == null)
            {
                ViewBag.Message = $"Role of {RoleId} of this Id is Not found";
                return View("NotFound");
            }
            else
            {
                var model = new List<UserRoleViewModel>();

                foreach (var users in _userManager.Users)
                {
                    var Users = new UserRoleViewModel()
                    {
                        UserName = users.UserName,
                        UserId = users.Id
                    };

                    if (await _userManager.IsInRoleAsync(users, role.Name))
                    {
                        Users.IsSelected = true;
                    }
                    else
                    {
                        Users.IsSelected = false;
                    }
                    model.Add(Users);
                }

                return View(model);
            }

        }

        [HttpPost]
        public async Task<IActionResult> EditUsersInRoles(List<UserRoleViewModel> model, string RoleId)
        {
            var role = await rolesManager.FindByIdAsync(RoleId);

            if (role == null)
            {
                ViewBag.ErrorMessage = $"Role with Id={RoleId} not found";
                return View("NotFound");
            }
            else
            {
                for (int i = 0; i < model.Count; i++)
                {
                    var user=await _userManager.FindByIdAsync(model[i].UserId);

                    IdentityResult result = null;

                    if (model[i].IsSelected == true&&!(await _userManager.IsInRoleAsync(user,role.Name)))
                        result= await _userManager.AddToRoleAsync(user, role.Name);
                    else if(!model[i].IsSelected&&await _userManager.IsInRoleAsync(user,role.Name))
                    {
                        result = await _userManager.RemoveFromRoleAsync(user, role.Name);
                    }
                    else
                    {
                        continue;
                    }

                    if (result.Succeeded)
                    {
                        if(i<(model.Count-1))
                            continue;
                        else
                        {
                            return RedirectToAction("EditRole", new {Id = RoleId});
                        }
                    }
                }

                
            }

            return View("NotFound");

        }
    }
}

And for EditUsersInRoles html template is below

@model List<UserRoleViewModel>
@{
    ViewData["Title"] = "EditUsersInRoles";
}

<h1>EditUsersInRoles</h1>
@{
    var RoleID = ViewBag.RoleId;
}

<form method="post">
    
    <div class="card">
        
        <div class="card-header">
            <h3>Add and Remove Users For this Role</h3>
        </div>
        
        <div class="card-body">
            @for (int i = 0; i < Model.Count; i++)
            {
                <div class="form-check">
                    <input type="hidden" asp-for="@Model[i].UserId" />
                    <input type="hidden" asp-for="@Model[i].UserName" />
                    <input asp-for="@Model[i].IsSelected" class="form-check-input" />
                    <label>@Model[i].UserName</label>
                </div>    
            }

        </div>
        
        <div class="card-footer">
            <input type="submit" value="Update" class="btn btn-primary" />
            <a type="submit" class="btn btn-primary" asp-action="EditUsersInRoles" asp-controller="Rolemanag" asp-route-RoleId="@RoleID">Cancel</a>
        </div>

    </div>

</form>

Now when we click on add and remove user roles below is output

Edit The Users In Roles
Edit The Users In Roles

GitHub Project Link: https://github.com/Sagar-Jaybhay/LearnAspNetCore

Sagar Jaybhay, from Maharashtra, India, is currently a Senior Software Developer. He has continuously grown in the roles that he has held in the more than seven years he has been with this company. Sagar Jaybhay is an excellent team member and prides himself on his work contributions to his team and company as a whole.

Related posts