Here we are assuming that reader has basic knowledge of ASP.NET MVC and he/she knows how the view, controller and Entity framework works. In case you do not know basics of ASP.NET MVC, please read beginners level articles from
of DotNetFunda.com.
Lets get started managing Roles in ASP.NET Identity
By default when an ASP.NET MVC default application is run and auto migration is on, registering a user automatically creates following table (starting with Asp....) in the database where
- AspNetRoles - stores roles information contains Id and Name columns
- AspNetUsers - stores users information contains Id, UserName, PasswordHash, SecurityStamp and Discriminator columns
- AspNetUserRoles - stores user and role id contains UserId and RoleId columns
Explanations of other tables are not given here as those of out of context of this article.
As by default we do not get default Model class for ASP.NET Identity related database tables, so we may need to create our controller and view manually. In this case, we have a separate controller and view folder for Roles.
Application assumption
Here, our assumption is that we already have an IdentityModels.cs class in the Models folder whose code looks like below (in ASP.NET MVC 5, it gets created automatically).
// You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
public class ApplicationUser : IdentityUser
{
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection")
{
}
}
In all the Action methods of the RolesController, no authorize attribute has been (to check for the admin user who is authorized to deal with Roles) used just for the shake of clarity and make the code snippet easily readable and understandable.
Creating a new Role with ASP.NET Identity
To create a new Role, we have below view and the code snippet for this is below.
@{
ViewBag.Title = "Create";
}
<h2>Create Role</h2>
@Html.ActionLink("List Roles", "Index") | @Html.ActionLink("Manage User Role", "ManageUserRoles")
<hr/>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<div>
Role name
</div>
<p>
@Html.TextBox("RoleName")
</p>
<input type="submit" value="Save" />
}
In the above code snippet, we have a simple TextBox named "RoleName" and some general form related code, please note that we do not have a @model
directive here. The controller methods looks like below.
Namespace required in order to work with Roles are below
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
Controller method for Create view looks like below
// GET: /Roles/Create
public ActionResult Create()
{
return View();
}
//
// POST: /Roles/Create
[HttpPost]
public ActionResult Create(FormCollection collection)
{
try
{
context.Roles.Add(new Microsoft.AspNet.Identity.EntityFramework.IdentityRole()
{
Name = collection["RoleName"]
});
context.SaveChanges();
ViewBag.ResultMessage = "Role created successfully !";
return RedirectToAction("Index");
}
catch
{
return View();
}
}
The first
Create
method simply returns the Create view and second
Create
method accepts
FormCollection
object as parameter and uses context object (instance of
ApplicationDbContext
) to add a Role to the Roles collection. Note that despite our roles table in the database name is
AspNetRoles
, the model class name is
IdentityRole
(part of ASP.NET Identity provider). Calling SaveChanges method saves the new role into the database.
To list roles using ASP.NET Identity, we have below view code.
@model IEnumerable<Microsoft.AspNet.Identity.EntityFramework.IdentityRole>
@{
ViewBag.Title = "Index";
}
<h2>Roles Listing </h2>
@Html.ActionLink("Create New Role", "Create") | @Html.ActionLink("Manage User Role", "ManageUserRoles")
<hr/>
<div>
@foreach (var role in Model)
{
<p><strong>@role.Name | </strong>
<span onclick="return confirm('Are you sure to delete?')"><a href="/Roles/Delete?RoleName=@role.Name" class="delLink" style="color:red;">Delete</a></span> |
@Html.ActionLink("Edit", "Edit", new { roleName = @role.Name })
</p>
}
</div>
In the above code snippet, the model of this view is IdentityRole
and in foreach loop, all the role from the Roles collection are being listed. While listing roles, we have also created link to Delete and Edit a particular Role.
The controller method to list ASP.NET Identity role looks like below
public ActionResult Index()
{
var roles = context.Roles.ToList();
return View(roles);
}
In the above code snippet, we are simply getting the Roles collection from ApplicationDbContext and returning to the View.
Deleting a Role using ASP.NET Identity
Clicking Delete link from the list of Roles deletes a particulrole from the database, and here is the action method of the RolesController.
public ActionResult Delete(string RoleName)
{
var thisRole = context.Roles.Where(r => r.Name.Equals(RoleName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
context.Roles.Remove(thisRole);
context.SaveChanges();
return RedirectToAction("Index");
}
Where we are getting the selected Role from the database and calling
Remove
method of the Roles collection. Calling SaveChanges method of the ApplicationDbContext object deletes the selected role from the database.
Editing Role using ASP.NET Identity
To edit role, we have above View and the code looks like below
@model Microsoft.AspNet.Identity.EntityFramework.IdentityRole
@{
ViewBag.Title = "Edit";
}
<h2>Edit Role</h2>
@Html.ActionLink("List Roles", "Index") | @Html.ActionLink("Manage User Role", "ManageUserRoles")
<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" />
}
In the above view code, IdentityRole
class is our model whose field is getting populated in the form to edit the role.
The controller Edit methods looks like below
//
// GET: /Roles/Edit/5
public ActionResult Edit(string roleName)
{
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
{
context.Entry(role).State = System.Data.Entity.EntityState.Modified;
context.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return View();
}
}
In the above code snippet, the first method accept roleName as parameter and based on that we retrieve the role from the database and returns to the View.
The second method accept IdentityRole
as parameter and update the record to the database.
Managing roles for a particular User in ASP.NET Identity
To manage role for a particular user in ASP.NET Identity, we have below view that has more than one form to
- Add a role to the user
- Get roles for a user and
- Delete/Detach a user from a particular role
The code for the above view looks like below
@{
ViewBag.Title = "ManageUserRoles";
}
<h2>Manage User Roles</h2>
@Html.ActionLink("Create New Role", "Create") | @Html.ActionLink("Manage User Role", "ManageUserRoles")
<hr/>
<h2>Role Add to User</h2>
@using (Html.BeginForm("RoleAddToUser", "Roles"))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<p>
Username : @Html.TextBox("UserName")
Role Name: @Html.DropDownList("RoleName", (IEnumerable <SelectListItem>) ViewBag.Roles, "Select ...")
</p>
<input type="submit" value="Save" />
}
<hr/>
<h3>Get Roles for a User</h3>
@using (Html.BeginForm("GetRoles", "Roles"))
{
@Html.AntiForgeryToken()
<p>
Username : @Html.TextBox("UserName")
<input type="submit" value="Get Roles for this User" />
</p>
}
@if (ViewBag.RolesForThisUser != null)
{
<div style="background-color:yellow;">
<h3>Roles for this user </h3>
<ol>
@foreach (string s in ViewBag.RolesForThisUser)
{
<li>@s</li>
}
</ol>
</div>
}
<hr />
<h3>Delete A User from a Role</h3>
@using (Html.BeginForm("DeleteRoleForUser", "Roles"))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<p>
Username : @Html.TextBox("UserName")
Role Name: @Html.DropDownList("RoleName", (IEnumerable<SelectListItem>)ViewBag.Roles, "Select ...")
</p>
<input type="submit" value="Delete this user from Role" />
}
The controller
ManageUserRoles method looks like this
public ActionResult ManageUserRoles()
{
// prepopulat roles for the view dropdown
var list = context.Roles.OrderBy(r => r.Name).ToList().Select(rr =>
new SelectListItem { Value = rr.Name.ToString(), Text = rr.Name }).ToList();
ViewBag.Roles = list;
return View();
}
Where we are simply getting the Roles list and setting into the Roles ViewBag that will be used to populate the Roles DropDown in the view.
Adding a role to the User using ASP.NET Identity
(DO not get confused and do not worry too much about sentence formation, grammar or proper use of words :), you can also say Adding a user to the Role. Just have fun with this childish title :D)
Where the first Form has simply a UserName textbox and a RoleName dropdown list that contains current Roles from the database. Submitting the form sends form data to RoleAddToUser
action method of the RolesController.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult RoleAddToUser(string UserName, string RoleName)
{
ApplicationUser user = context.Users.Where(u => u.UserName.Equals(UserName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
var account = new AccountController();
account.UserManager.AddToRole(user.Id, RoleName);
ViewBag.ResultMessage = "Role created successfully !";
// prepopulat roles for the view dropdown
var list = context.Roles.OrderBy(r => r.Name).ToList().Select(rr => new SelectListItem { Value = rr.Name.ToString(), Text = rr.Name }).ToList();
ViewBag.Roles = list;
return View("ManageUserRoles");
}
In the above method, we are getting UserName and RoleName as parameter.
UserName is being used to get the ApplicationUser from context.Users collection. Then AccountController object is being used to access the UserManager object property and call its AddToRole
method by passing UserId from the ApplicationUser object and RoleName coming in from the form.
Next few lines of codes are just to list the roles in the DropDown list again as we are returning to the same (ManageUserRoles) view again.
Getting Roles for a user in ASP.NET Identity
In the second form, we have a UserName textbox and a button. Clicking button submits the form to the GetRoles
action method of the RolesController.
The GetRoles controller method looks like below
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult GetRoles(string UserName)
{
if (!string.IsNullOrWhiteSpace(UserName))
{
ApplicationUser user = context.Users.Where(u => u.UserName.Equals(UserName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
var account = new AccountController();
ViewBag.RolesForThisUser = account.UserManager.GetRoles(user.Id);
// prepopulat roles for the view dropdown
var list = context.Roles.OrderBy(r => r.Name).ToList().Select(rr => new SelectListItem { Value = rr.Name.ToString(), Text = rr.Name }).ToList();
ViewBag.Roles = list;
}
return View("ManageUserRoles");
}
In the above code snippet, we are getting the ApplicationUser object using the UserName. Then AccountController object is being used to get the Roles for that particular UserName using its id.
Deleting a User from a Role
(Another title, have fun :D)
In the third form, we have a UserName textbox and RoleName dropdown list. Clicking button submits the form to DeleteRoleForUser action method and below is the code snippet for that.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult DeleteRoleForUser(string UserName, string RoleName)
{
var account = new AccountController();
ApplicationUser user = context.Users.Where(u => u.UserName.Equals(UserName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
if (account.UserManager.IsInRole(user.Id, RoleName))
{
account.UserManager.RemoveFromRole(user.Id, RoleName);
ViewBag.ResultMessage = "Role removed from this user successfully !";
}
else
{
ViewBag.ResultMessage = "This user doesn't belong to selected role.";
}
// prepopulat roles for the view dropdown
var list = context.Roles.OrderBy(r => r.Name).ToList().Select(rr => new SelectListItem { Value = rr.Name.ToString(), Text = rr.Name }).ToList();
ViewBag.Roles = list;
return View("ManageUserRoles");
}
In the above code snippet, we are getting ApplicationUser and then checking whether this user belongs to the selected Role or not (using AccountController object), if it is then calling the RemoveFromRole
method by passing UserId and RoleName parameter that removes the user from the role.
Source code: The entire source code for this article can be downloaded from
GitHub directly, also you are most welcome to enhance or improve it by participating in it on GitHub.
Conclusion
In this article, we learnt how to develop User Interface to create a new Role, Edit a role, Delete a role, View roles attached to a particular user and manage a role for a particular user using ASP.NET Identity in ASP.NET MVC.
Hope this article would be useful.
If you liked this article, please share this to your friends and colleagues and do let us know your comment or feedback. Thanks for reading.
Reference