Simple Role Manager in ASP.NET MVC 5

Chrisc1073
Posted by in ASP.NET MVC category on for Intermediate level | Points: 250 | Views : 3137 red flag
Rating: 5 out of 5  
 2 vote(s)

This is a tutorial to create a simple Role Manager for ASP.NET MVC 5. It is simple because almost everything you need is on one view. I provide this because I found it hard to find anything that I could add to my webpage to provide me with simple role management functionality. The source is based largely on the works referenced herein and code snippets I needed to modify to adapt it to work for me.

In summary, this is what I wanted to find when I went looking...so hopefully this will get you managing your roles fast.
Recommendation
Read Working with Roles in ASP.NET Identity for MVC before this article.

Introduction

This is basically a simplification and slight modification of Sheo Narayan's code http://www.dotnetfunda.com/articles/show/2898/working-with-roles-in-aspnet-identity-for-mvc.

It is a very good article however several things didn't work when tried to use it so spent a bit of time modifying things. 

The code herein will produce a simple Dashboard to Manage Roles and Users in those Roles.  It only requires one controller and two views.  Bootstrap is used for formatting.  It should look like this when you're done:




Prerequisites
You already have created a new ASP.NET Web Application using MVC.  In this article, "Individual User Accounts" type of Authentication is used.

You have a basic working knowledge of general MVC programming.  You have probably built a web page and are now wondering how you manage roles and users.  

Tasks
Basically you will create one controller (in Step 1) and two views.  The Index View really does 99% of what you need.  The other edit view is just to rename Roles if you need to.  This article considered renaming roles an infrequent thing to do so is left on a second view.  Lastly in Step 5 you just want to add your Role Manager to your Menu and you're done !

Step 1: Create a RolesController.cs in your existing project by right clicking the Controllers Folder, selecting Add and then selecting the Controllers Folder "MVC 5 Controller Empty".  
Below is the code to paste into this controller but before you do this check the "using" headers to ensure you dont write over YOUR database name (highlighted in bold below.  It will most likely be different to mine called MyDatabase).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using MyDatabase.Models;

namespace MyDatabase.Controllers
{

    public class RolesController : Controller
    {
        

        public ActionResult Index()
        {
            // Populate Dropdown Lists
            var context = new Models.ApplicationDbContext();

            var rolelist = context.Roles.OrderBy(r => r.Name).ToList().Select(rr =>
            new SelectListItem { Value = rr.Name.ToString(), Text = rr.Name }).ToList();
            ViewBag.Roles = rolelist;

            var userlist = context.Users.OrderBy(u => u.UserName).ToList().Select(uu =>
            new SelectListItem { Value = uu.UserName.ToString(), Text = uu.UserName }).ToList();
            ViewBag.Users = userlist;

            ViewBag.Message = "";

            return View();
        }


        // GET: /Roles/Create
        public ActionResult Create()
        {
            return View();
        }

        //
        // POST: /Roles/Create
        [HttpPost]
        public ActionResult Create(FormCollection collection)
        {
            
            try
            {
                var context = new Models.ApplicationDbContext();
                context.Roles.Add(new Microsoft.AspNet.Identity.EntityFramework.IdentityRole()
                {
                    Name = collection["RoleName"]
                });
                context.SaveChanges();
                ViewBag.Message = "Role created successfully !";
                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }


        public ActionResult Delete(string RoleName)
        {
            var context = new Models.ApplicationDbContext();
            var thisRole = context.Roles.Where(r => r.Name.Equals(RoleName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
            context.Roles.Remove(thisRole);
            context.SaveChanges();
            return RedirectToAction("Index");
        }

        //
        // GET: /Roles/Edit/5
        public ActionResult Edit(string roleName)
        {
            var context = new Models.ApplicationDbContext();
            var thisRole = context.Roles.Where(r => r.Name.Equals(roleName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();

            return View(thisRole);
        }

        //
        // POST: /Roles/Edit/5
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(Microsoft.AspNet.Identity.EntityFramework.IdentityRole role)
        {
            try
            {
                var context = new Models.ApplicationDbContext();
                context.Entry(role).State = System.Data.Entity.EntityState.Modified;
                context.SaveChanges();

                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }

         
        //  Adding Roles to a user
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult RoleAddToUser(string UserName, string RoleName)
        {
            var context = new Models.ApplicationDbContext();

            if (context == null)
            {
                throw new ArgumentNullException("context", "Context must not be null.");
            }

            ApplicationUser user = context.Users.Where(u => u.UserName.Equals(UserName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();

            var userStore = new UserStore<ApplicationUser>(context);
            var userManager = new UserManager<ApplicationUser>(userStore);
            userManager.AddToRole(user.Id, RoleName);


            ViewBag.Message = "Role created successfully !";

            // Repopulate Dropdown Lists
            var rolelist = context.Roles.OrderBy(r => r.Name).ToList().Select(rr => new SelectListItem { Value = rr.Name.ToString(), Text = rr.Name }).ToList();
            ViewBag.Roles = rolelist;
            var userlist = context.Users.OrderBy(u => u.UserName).ToList().Select(uu =>
            new SelectListItem { Value = uu.UserName.ToString(), Text = uu.UserName }).ToList();
            ViewBag.Users = userlist;

            return View("Index");
        }


        //Getting a List of Roles for a User
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult GetRoles(string UserName)
        {
            if (!string.IsNullOrWhiteSpace(UserName))
            {
                var context = new Models.ApplicationDbContext();
                ApplicationUser user = context.Users.Where(u => u.UserName.Equals(UserName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
 
                var userStore = new UserStore<ApplicationUser>(context);
                var userManager = new UserManager<ApplicationUser>(userStore);
                ViewBag.RolesForThisUser = userManager.GetRoles(user.Id);


                // Repopulate Dropdown Lists
                var rolelist = context.Roles.OrderBy(r => r.Name).ToList().Select(rr => new SelectListItem { Value = rr.Name.ToString(), Text = rr.Name }).ToList();
                ViewBag.Roles = rolelist;
                var userlist = context.Users.OrderBy(u => u.UserName).ToList().Select(uu =>
                new SelectListItem { Value = uu.UserName.ToString(), Text = uu.UserName }).ToList();
                ViewBag.Users = userlist;
                ViewBag.Message = "Roles retrieved successfully !";
            }

            return View("Index");
        }

        //Deleting a User from A Role
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteRoleForUser(string UserName, string RoleName)
        {
            var account = new AccountController();
            var context = new Models.ApplicationDbContext();
            ApplicationUser user = context.Users.Where(u => u.UserName.Equals(UserName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();

            var userStore = new UserStore<ApplicationUser>(context);
            var userManager = new UserManager<ApplicationUser>(userStore);


            if (userManager.IsInRole(user.Id, RoleName))
            {
                userManager.RemoveFromRole(user.Id, RoleName);
                ViewBag.Message = "Role removed from this user successfully !";
            }
            else
            {
                ViewBag.Message = "This user doesn't belong to selected role.";
            }

            // Repopulate Dropdown Lists
            var rolelist = context.Roles.OrderBy(r => r.Name).ToList().Select(rr => new SelectListItem { Value = rr.Name.ToString(), Text = rr.Name }).ToList();
            ViewBag.Roles = rolelist;
            var userlist = context.Users.OrderBy(u => u.UserName).ToList().Select(uu =>
            new SelectListItem { Value = uu.UserName.ToString(), Text = uu.UserName }).ToList();
            ViewBag.Users = userlist;

            return View("Index");
        }

    }
}

Step 2:  Create a Views Folder called "Roles".   Then create your two views in this folder called Edit and Index as shown below.  




Step 3: Here is the code to paste into the Index View:


@{
    ViewBag.Title = "ManageUserRoles";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<div class="row col-sm-12 col-lg-12 col-md-12">
    <h1>Role Manager</h1>
    <br />
</div>

<div class="row col-sm-12 col-lg-12 col-md-12">


    <div class="col-sm-6 col-lg-6 col-md-6">
        <div class="panel panel-primary">
            <div class="panel-heading">
                <h4>Role List</h4>
            </div>
            <div class="panel-body">
                <table class="table table-striped table-hover col-sm-6 col-lg-6 col-md-6 ">
                    @foreach (var role in ViewBag.Roles)
            {
                        <tr>
                            <td class="col-sm-1 col-lg-5 col-md-5">
                                <strong>@role.Text </strong>
                            </td>
                            <td class="col-sm-1 col-lg-1 col-md-1">
                                <span onclick="return confirm('Are you sure to delete?')"><a href="/Roles/Delete?RoleName=@role.Text" class="delLink" style="color:red;">Delete</a></span> |
                                @Html.ActionLink("Edit", "Edit", new { roleName = @role.Text })
                            </td>
                        </tr>
                    }
                </table>
            </div> <!-- End Panel Body-->
        </div> <!-- End Panel -->

        <div class="panel panel-primary">
            <div class="panel-heading">
                <h4>Create A New Role</h4>
            </div>
            <div class="panel-body">
                @using (Html.BeginForm("Create", "Roles", new { @class = "form-horizontal" }))
            {
                    @Html.AntiForgeryToken()
                    @Html.ValidationSummary(true)

                    <div>
                        Role name: @Html.TextBox("RoleName")
                        <input type="submit" value="Save" class="btn-primary" />
                    </div>
                }

            </div> <!--End Panel Body-->
        </div> <!--End Panel-->
    </div> <!--End First Column-->

    <div class="col-sm-6 col-lg-6 col-md-6">
        <div class="panel panel-primary">
            <div class="panel-heading">
                <h4>Add a Role to a User</h4>
            </div>
            <div class="panel-body">
                @using (Html.BeginForm("RoleAddToUser", "Roles"))
            {
                    @Html.AntiForgeryToken()
                    @Html.ValidationSummary(true)

                    <p>User Name: @Html.DropDownList("UserName", (IEnumerable<SelectListItem>)ViewBag.Users, "Select ...")</p>
                    <p>Role Name: @Html.DropDownList("RoleName", (IEnumerable<SelectListItem>)ViewBag.Roles, "Select ...")</p>
                    <p><input type="submit" value="Save" class="btn-primary" /></p>

                }
            </div> <!-- End Panel Body-->
        </div> <!-- End Panel -->


        <div class="panel panel-primary">
            <div class="panel-heading">
                <h4>List Roles for a User</h4>
            </div>
            <div class="panel-body">
                @using (Html.BeginForm("GetRoles", "Roles"))
            {
                    @Html.AntiForgeryToken()
                    <p>
                        User Name: @Html.DropDownList("UserName", (IEnumerable<SelectListItem>)ViewBag.Users, "Select ...")
                        <input type="submit" value="Get Roles for this User" class="btn-primary" />
                    </p>
                }

                @if (ViewBag.RolesForThisUser != null)
            {
                    <div class="alert-info">
                        <strong>Roles for this user </strong>
                        <ol>
                            @foreach (string s in ViewBag.RolesForThisUser)
                {
                                <li>@s</li>
                            }
                        </ol>
                    </div>
                }
            </div> <!-- End Panel Body-->
        </div> <!-- End Panel -->

        <div class="panel panel-primary">
            <div class="panel-heading">
                <h4>Remove Role from User</h4>
            </div>
            <div class="panel-body">
                @using (Html.BeginForm("DeleteRoleForUser", "Roles"))
            {
                    @Html.AntiForgeryToken()
                    @Html.ValidationSummary(true)

                    <p>User Name: @Html.DropDownList("UserName", (IEnumerable<SelectListItem>)ViewBag.Users, "Select ...")</p>
                    <p>Role Name: @Html.DropDownList("RoleName", (IEnumerable<SelectListItem>)ViewBag.Roles, "Select ...")</p>
                    <p><input type="submit" value="Delete this user from Role" class="btn-primary" /></p>

                }
            </div> <!-- End Panel Body-->
        </div> <!-- End Panel -->

    </div> <!--End Second Column-->

</div>  <!--Overall Page Wrapper-->

<div class="alert-info col-sm-12 col-lg-12 col-md-12">
    @ViewBag.Message
</div>


Step 4:  Here is the code for the Edit View:

@model Microsoft.AspNet.Identity.EntityFramework.IdentityRole
@{
    ViewBag.Title = "Edit Roles";
}

<h2>Edit Role</h2>

@Html.ActionLink("Return to Role Manager", "Index") 
<hr />
@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)
    @Html.HiddenFor(model => model.Id)
    <div>
        Role name
    </div>
    <p>
        @Html.TextBoxFor(model => model.Name)
    </p>
    <input type="submit" value="Save" />
}


Step 5:  (Optional) Add a menu list item in your _Layout.cshtml so you can access it and you're good to go !
<li>@Html.ActionLink("Role Manager", "Index", "Roles")</li>



Conclusion

Voila, you should have a simple dashboard that allows you to create, edit and delete roles as well as assign users to roles.  It is by no means a polished product but should at least be functional. Feel free to spice it up !

Reference

http://www.dotnetfunda.com/articles/show/2898/working-with-roles-in-aspnet-identity-for-mvc

Page copy protected against web site content infringement by Copyscape

About the Author

Chrisc1073
Full Name: Chris C
Member Level: Starter
Member Status: Member
Member Since: 2/13/2016 12:00:57 AM
Country: Australia



Login to vote for this post.

Comments or Responses

Posted by: Sheonarayan on: 2/14/2016 | Points: 25
Excellent extension of the linked article Chris.

Keep it up!
Posted by: Crandallman on: 8/27/2016 | Points: 25
Looks great Chris exactly what I was looking for, however, I'm having some issues with
var userManager = new UserManager<ApplicationUser>(userStore);
I'm getting an error as it is looking for some more required formal parameters. Did I miss adding some code somewhere?

Login to post response

Comment using Facebook(Author doesn't get notification)