I'm pretty new to ASP.NET MVC, and I've been looking at a lot of different ways of adding User Roles for my ASP.NET MVC site. I want to use the users' database(s) that are automatically made for you when you make a new ASP.NET MVC project.
That contain the tables:
I've been looking at a few tutorials and it's a bit of a minefield for beginners I think.
All I want to be able to do is something like this:
[Authorize(Roles = "admin")]
public ActionResult Index()
{
Return View();
}
So users with the role administrator can access the index page.
The first step is to create the admin
role. This is easy enough:
context.Roles.Add(new IdentityRole { Name = "admin" });
context.SaveChanges();
To add the role to an existing user:
var role = context.Roles.SingleOrDefault(m => m.Name == "admin");
user.Roles.Add(new IdentityUserRole { RoleId = role.Id });
Both of these steps can and should be handled in your Seed
method of Migrations\Configuration.cs
, along with creating any initial users that should be administrators.
For the ability of administrators to add roles to other users, you've got the first step covered already: protect the action with [Authorize(Roles = "admin")]
.
Next, you'll need a view model to work with your user. Something like the following:
public class UserViewModel
{
// User properties you'd like to edit goes here
public List<int> SelectedRoleIds { get; set; }
public IEnumerable<SelectListItem> RoleChoices { get; set; }
}
You'll need to map your ApplicationUser
to/from this view model. Then, you'll need to manually populate the two role properties in UserViewModel
:
RoleChoices
should be an enumerable of all available roles:
model.RoleChoices = context.Roles.Select(m => new SelectListItem
{
Value = m.Id,
Text = m.Name
});
SelectedRoleIds
should be a list of the ids of all roles currently assigned to the user:
model.SelectedRoleIds = user.Roles.Select(m => m.RoleId);
In your view, then, you'll construct your multiselect:
@Html.ListBoxFor(m => m.SelectedRoleIds, Model.RoleChoices)
When creating a new user, you can simply set the user's roles directly on post:
user.Roles = model.SelectedRoleIds.Select(m => new IdentityUserRole { RoleId = m });
When editing an existing user, greater care has to be taken, since you'll get integrity errors if you save the same role id twice for the same user. First, you'll need to remove any roles that have been deselected:
user.Roles.Where(m => !model.SelectedRoleIds.Contains(m.RoleId))
.ToList().ForEach(role => user.Roles.Remove(role));
Then, you'll need to add any newly selected roles:
var existingUserRoles = user.Roles.Select(m => m.RoleId);
model.SelectedRoleIds.Except(existingUserRoles)
.ToList().ForEach(roleId => user.Roles.Add(new IdentityUserRole
{
RoleId = roleId
}));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With