新建asp.net core web应用
添加RolesAdminController
[Authorize(Roles = "Admin")] public class RolesAdminController : Controller { private UserManager<ApplicationUser> _userManager; private RoleManager<IdentityRole> _roleManager; private readonly ILogger _logger; public RolesAdminController(UserManager<ApplicationUser> userManager, RoleManager<IdentityRole> roleManager, ILogger<AccountController> logger) { _userManager = userManager; _roleManager = roleManager; _logger = logger; } // // GET: /Roles/ public ActionResult Index() { return View(_roleManager.Roles); } // // GET: /Roles/Details/5 public async Task<ActionResult> Details(string id) { if (id == null) { throw new ApplicationException(); } var role = await _roleManager.FindByIdAsync(id); // Get the list of Users in this Role var users = new List<ApplicationUser>(); // Get the list of Users in this Role foreach (var user in _userManager.Users.ToList()) { if (await _userManager.IsInRoleAsync(user, role.Name)) { users.Add(user); } } ViewBag.Users = users; ViewBag.UserCount = users.Count(); return View(role); } // // GET: /Roles/Create public ActionResult Create() { return View(); } // // POST: /Roles/Create [HttpPost] public async Task<ActionResult> Create(IdentityRole roleViewModel) { if (ModelState.IsValid) { var role = new IdentityRole(roleViewModel.Name); var roleresult = await _roleManager.CreateAsync(role); if (!roleresult.Succeeded) { AddErrors(roleresult); return View(); } return RedirectToAction("Index"); } return View(); } // // GET: /Roles/Edit/Admin public async Task<ActionResult> Edit(string id) { if (id == null) { throw new ApplicationException(); } var role = await _roleManager.FindByIdAsync(id); if (role == null) { throw new ApplicationException(); } IdentityRole roleModel = new IdentityRole { Id = role.Id, Name = role.Name }; return View(roleModel); } [HttpPost] [ValidateAntiForgeryToken] public async Task<ActionResult> Edit(IdentityRole roleModel) { if (ModelState.IsValid) { var role = await _roleManager.FindByIdAsync(roleModel.Id); role.Name = roleModel.Name; await _roleManager.UpdateAsync(role); return RedirectToAction("Index"); } return View(); } // // GET: /Roles/Delete/5 public async Task<ActionResult> Delete(string id) { if (id == null) { throw new ApplicationException(); } var role = await _roleManager.FindByIdAsync(id); if (role == null) { throw new ApplicationException(); } return View(role); } // // POST: /Roles/Delete/5 [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public async Task<ActionResult> DeleteConfirmed(string id, string deleteUser) { if (ModelState.IsValid) { if (id == null) { throw new ApplicationException(); } var role = await _roleManager.FindByIdAsync(id); if (role == null) { throw new ApplicationException(); } IdentityResult result; if (deleteUser != null) { result = await _roleManager.DeleteAsync(role); } else { result = await _roleManager.DeleteAsync(role); } if (!result.Succeeded) { AddErrors(result); return View(); } return RedirectToAction("Index"); } return View(); } #region Helpers private void AddErrors(IdentityResult result) { foreach (var error in result.Errors) { ModelState.AddModelError(string.Empty, error.Description); } } private IActionResult RedirectToLocal(string returnUrl) { if (Url.IsLocalUrl(returnUrl)) { return Redirect(returnUrl); } else { return RedirectToAction(nameof(HomeController.Index), "Home"); } } #endregion }
添加对应的View
index
@model IEnumerable<IdentityRole> @{ ViewBag.Title = "Index"; } <h2>Index</h2> <p> @Html.ActionLink("Create New", "Create") </p> <table class="table"> <tr> <th> @Html.DisplayNameFor(model => model.Name) </th> <th> </th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.Name) </td> <td> @Html.ActionLink("Edit", "Edit", new { id = item.Id }) | @Html.ActionLink("Details", "Details", new { id = item.Id }) | @Html.ActionLink("Delete", "Delete", new { id = item.Id }) </td> </tr> } </table>
create
@model IdentityRole @{ ViewBag.Title = "Create"; } <h2>Create.</h2> @using (Html.BeginForm()) { @Html.AntiForgeryToken() <div class="form-horizontal"> <h4>Role.</h4> <hr /> @Html.ValidationSummary(true) <div class="form-group"> @Html.LabelFor(model => model.Name, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.TextBoxFor(model => model.Name, new { @class = "form-control" }) @Html.ValidationMessageFor(model => model.Name) </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" value="Create" class="btn btn-default" /> </div> </div> </div> } <div> @Html.ActionLink("Back to List", "Index") </div> @section Scripts { @await Html.PartialAsync("_ValidationScriptsPartial") }
edit
@model IdentityRole @{ ViewBag.Title = "Edit"; } <h2>Edit.</h2> @using (Html.BeginForm()) { @Html.AntiForgeryToken() <div class="form-horizontal"> <h4>Roles.</h4> <hr /> @Html.ValidationSummary(true) @Html.HiddenFor(model => model.Id) <div class="form-group"> @Html.LabelFor(model => model.Name, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.TextBoxFor(model => model.Name, new { @class = "form-control" }) @Html.ValidationMessageFor(model => model.Name) </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" value="Save" class="btn btn-default" /> </div> </div> </div> } <div> @Html.ActionLink("Back to List", "Index") </div> @section Scripts { @await Html.PartialAsync("_ValidationScriptsPartial") }
details
@model IdentityRole @{ ViewBag.Title = "Details"; } <h2>Role Details.</h2> <div> <h4>Roles.</h4> <hr /> <dl class="dl-horizontal"> <dt> @Html.DisplayNameFor(model => model.Name) </dt> <dd> @Html.DisplayFor(model => model.Name) </dd> </dl> </div> <h4>List of users in this role</h4> @if (ViewBag.UserCount == 0) { <hr /> <p>No users found in this role.</p> } <table class="table"> @foreach (var item in ViewBag.Users) { <tr> <td> @item.UserName </td> </tr> } </table> <p> @Html.ActionLink("Edit", "Edit", new { id = Model.Id }) | @Html.ActionLink("Back to List", "Index") </p>
delete
@model IdentityRole @{ ViewBag.Title = "Delete"; } <h2>Delete.</h2> <h3>Are you sure you want to delete this Role? </h3> <p>Deleting this Role will remove all users from this role. It will not delete the users.</p> <div> <h4>Delete Role.</h4> <hr /> <dl class="dl-horizontal"> <dt> @Html.DisplayNameFor(model => model.Name) </dt> <dd> @Html.DisplayFor(model => model.Name) </dd> </dl> @using (Html.BeginForm()) { @Html.AntiForgeryToken() <div class="form-actions no-color"> <input type="submit" value="Delete" class="btn btn-default" /> | @Html.ActionLink("Back to List", "Index") </div> } </div>
添加UsersAdminController
[Authorize(Roles = "Admin")] public class UsersAdminController : Controller { public UsersAdminController(UserManager<ApplicationUser> userManager, RoleManager<IdentityRole> roleManager, ILogger<AccountController> logger) { _userManager = userManager; _roleManager = roleManager; _logger = logger; } private UserManager<ApplicationUser> _userManager; private RoleManager<IdentityRole> _roleManager; private readonly ILogger _logger; // // GET: /Users/ public async Task<ActionResult> Index() { return View(await _userManager.Users.ToListAsync()); } // // GET: /Users/Details/5 public async Task<ActionResult> Details(string id) { if (id == null) { throw new ApplicationException(); } var user = await _userManager.FindByIdAsync(id); ViewBag.RoleNames = await _userManager.GetRolesAsync(user); return View(user); } // // GET: /Users/Create public async Task<ActionResult> Create() { //Get the list of Roles ViewBag.RoleId = new SelectList(await _roleManager.Roles.ToListAsync(), "Name", "Name"); return View(); } // // POST: /Users/Create [HttpPost] public async Task<ActionResult> Create(RegisterViewModel userViewModel, params string[] selectedRoles) { if (ModelState.IsValid) { var user = new ApplicationUser { UserName = userViewModel.Email, Email = userViewModel.Email, }; // Then create: var adminresult = await _userManager.CreateAsync(user, userViewModel.Password); //Add User to the selected Roles if (adminresult.Succeeded) { if (selectedRoles != null) { var result = await _userManager.AddToRolesAsync(user, selectedRoles); if (!result.Succeeded) { AddErrors(result); ViewBag.RoleId = new SelectList(await _roleManager.Roles.ToListAsync(), "Name", "Name"); return View(); } } } else { AddErrors(adminresult); ViewBag.RoleId = new SelectList(_roleManager.Roles, "Name", "Name"); return View(); } return RedirectToAction("Index"); } ViewBag.RoleId = new SelectList(_roleManager.Roles, "Name", "Name"); return View(); } // // GET: /Users/Edit/1 public async Task<ActionResult> Edit(string id) { if (id == null) { throw new ApplicationException(); } var user = await _userManager.FindByIdAsync(id); if (user == null) { throw new ApplicationException(); } var userRoles = await _userManager.GetRolesAsync(user); return View(new EditUserViewModel() { Id = user.Id, Email = user.Email, RolesList = _roleManager.Roles.ToList().Select(x => new SelectListItem() { Selected = userRoles.Contains(x.Name), Text = x.Name, Value = x.Name }) }); } // // POST: /Users/Edit/5 [HttpPost] [ValidateAntiForgeryToken] public async Task<ActionResult> Edit(EditUserViewModel editUser, params string[] selectedRole) { if (ModelState.IsValid) { var user = await _userManager.FindByIdAsync(editUser.Id); if (user == null) { throw new ApplicationException(); } user.UserName = editUser.Email; user.Email = editUser.Email; var userRoles = await _userManager.GetRolesAsync(user); selectedRole = selectedRole ?? new string[] { }; var result = await _userManager.AddToRolesAsync(user, selectedRole.Except(userRoles).ToArray<string>()); if (!result.Succeeded) { AddErrors(result); return View(); } result = await _userManager.RemoveFromRolesAsync(user, userRoles.Except(selectedRole).ToArray<string>()); if (!result.Succeeded) { AddErrors(result); return View(); } return RedirectToAction("Index"); } ModelState.AddModelError("", "Something failed."); return View(); } // // GET: /Users/Delete/5 public async Task<ActionResult> Delete(string id) { if (id == null) { throw new ApplicationException(); } var user = await _userManager.FindByIdAsync(id); if (user == null) { throw new ApplicationException(); } return View(user); } // // POST: /Users/Delete/5 [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public async Task<ActionResult> DeleteConfirmed(string id) { if (ModelState.IsValid) { if (id == null) { throw new ApplicationException(); } var user = await _userManager.FindByIdAsync(id); if (user == null) { throw new ApplicationException(); } var result = await _userManager.DeleteAsync(user); if (!result.Succeeded) { AddErrors(result); return View(); } return RedirectToAction("Index"); } return View(); } #region Helpers private void AddErrors(IdentityResult result) { foreach (var error in result.Errors) { ModelState.AddModelError(string.Empty, error.Description); } } private IActionResult RedirectToLocal(string returnUrl) { if (Url.IsLocalUrl(returnUrl)) { return Redirect(returnUrl); } else { return RedirectToAction(nameof(HomeController.Index), "Home"); } } #endregion }
添加对应的EditUserViewModel
public class EditUserViewModel { public string Id { get; set; } [Required(AllowEmptyStrings = false)] [Display(Name = "Email")] [EmailAddress] public string Email { get; set; } public IEnumerable<SelectListItem> RolesList { get; set; } }
添加对应的view
index
@model IEnumerable<WebApplication2.Models.ApplicationUser> @{ ViewBag.Title = "Index"; } <h2>Index</h2> <p> @Html.ActionLink("Create New", "Create") </p> <table class="table"> <tr> <th> @Html.DisplayNameFor(model => model.UserName) </th> <th> </th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.UserName) </td> <td> @Html.ActionLink("Edit", "Edit", new { id = item.Id }) | @Html.ActionLink("Details", "Details", new { id = item.Id }) | @Html.ActionLink("Delete", "Delete", new { id = item.Id }) </td> </tr> } </table>
create
@model WebApplication2.Models.AccountViewModels.RegisterViewModel @{ ViewBag.Title = "Create"; } <h2>@ViewBag.Title.</h2> @using (Html.BeginForm("Create", "UsersAdmin", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) { @Html.AntiForgeryToken() <h4>Create a new account.</h4> <hr /> @Html.ValidationSummary("", new { @class = "text-error" }) <div class="form-group"> @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" }) <div class="col-md-10"> @Html.TextBoxFor(m => m.Email, new { @class = "form-control" }) </div> </div> <div class="form-group"> @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" }) <div class="col-md-10"> @Html.PasswordFor(m => m.Password, new { @class = "form-control" }) </div> </div> <div class="form-group"> @Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" }) <div class="col-md-10"> @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" }) </div> </div> <div class="form-group"> <label class="col-md-2 control-label"> Select User Role </label> <div class="col-md-10"> @foreach (var item in (SelectList)ViewBag.RoleId) { <input type="checkbox" name="SelectedRoles" value="@item.Value" class="checkbox-inline" /> @Html.Label("Role", item.Value, new { @class = "control-label" }) } </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" class="btn btn-default" value="Create" /> </div> </div> } @section Scripts { @await Html.PartialAsync("_ValidationScriptsPartial") }
edit
@model WebApplication2.Models.AdminViewModels.EditUserViewModel @{ ViewBag.Title = "Edit"; } <h2>Edit.</h2> @using (Html.BeginForm()) { @Html.AntiForgeryToken() <div class="form-horizontal"> <h4>Edit User Form.</h4> <hr /> @Html.ValidationSummary(true) @Html.HiddenFor(model => model.Id) <div class="form-group"> @Html.LabelFor(model => model.Email, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.TextBoxFor(m => m.Email, new { @class = "form-control" }) @Html.ValidationMessageFor(model => model.Email) </div> </div> <div class="form-group"> @Html.Label("Roles","", new { @class = "control-label col-md-2" }) <span class=" col-md-10"> @foreach (var item in Model.RolesList) { <input type="checkbox" name="SelectedRole" value="@item.Value" checked="@item.Selected" class="checkbox-inline" /> @Html.Label("Role",item.Value, new { @class = "control-label" }) } </span> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" value="Save" class="btn btn-default" /> </div> </div> </div> } <div> @Html.ActionLink("Back to List", "Index") </div> @section Scripts { @await Html.PartialAsync("_ValidationScriptsPartial") }
details
@model WebApplication2.Models.ApplicationUser @{ ViewBag.Title = "Details"; } <h2>Details.</h2> <div> <h4>User</h4> <hr /> <dl class="dl-horizontal"> <dt> @Html.DisplayNameFor(model => model.UserName) </dt> <dd> @Html.DisplayFor(model => model.UserName) </dd> </dl> </div> <h4>List of roles for this user</h4> @if (ViewBag.RoleNames.Count == 0) { <hr /> <p>No roles found for this user.</p> } <table class="table"> @foreach (var item in ViewBag.RoleNames) { <tr> <td> @item </td> </tr> } </table> <p> @Html.ActionLink("Edit", "Edit", new { id = Model.Id }) | @Html.ActionLink("Back to List", "Index") </p>
delete
@model WebApplication2.Models.ApplicationUser @{ ViewBag.Title = "Delete"; } <h2>Delete.</h2> <h3>Are you sure you want to delete this User?</h3> <div> <h4>User.</h4> <hr /> <dl class="dl-horizontal"> <dt> @Html.DisplayNameFor(model => model.UserName) </dt> <dd> @Html.DisplayFor(model => model.UserName) </dd> </dl> @using (Html.BeginForm()) { @Html.AntiForgeryToken() <div class="form-actions no-color"> <input type="submit" value="Delete" class="btn btn-default" /> | @Html.ActionLink("Back to List", "Index") </div> } </div>
修改共享模板页
Shared/_layout.cshtml
<div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li> <li><a asp-area="" asp-controller="Home" asp-action="About">About</a></li> <li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li> @if (User!=null && User.IsInRole("Admin")) { <li>@Html.ActionLink("RolesAdmin", "Index", "RolesAdmin")</li> <li>@Html.ActionLink("UsersAdmin", "Index", "UsersAdmin")</li> } </ul> @await Html.PartialAsync("_LoginPartial") </div>
运行应用,注册两个账号
1@1.com具有Admin角色权限
2@2.com没有 Admin权限
1@1.com可以进入管理页面
2@2.com没有管理页面权限