如何使用 ASP.NET Core 2.1 中的网站界面为用户分配角色
How to assign roles to users using the website interface in ASP.NET Core 2.1
我正在尝试研究如何使用 ASP.Net 核心 2.1 在我的 Web 应用程序的管理界面中为用户分配角色。
我还没有找到答案。我的应用程序用户 ID 是基于字符串的,而不是整数。
目前我可以编辑用户、添加新用户、添加新角色删除角色、编辑角色名称,但无法为用户分配角色。
理想情况下,我想要做的是有一个视图,它有两个下拉列表。一个包含所有用户以及我可以分配的可用角色列表。
有没有人有任何关于如何实现这一目标的提示?
这是我当前的角色控制器。对于上下文,我使用的是存储库模式。并实现了一些身份模型、ApplicationUser、ApplicationUserRole 和 Application Role。
角色controller.cs:
[Authorize(Roles = "Admin")]
public class RolesController : Controller
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly RoleManager<ApplicationRole> _roleManager;
private IRepository _repo;
private readonly ApplicationDbContext _context;
public RolesController(UserManager<ApplicationUser> userManager,
RoleManager<ApplicationRole> roleManager, IRepository repo, ApplicationDbContext context)
{
_userManager = userManager;
_roleManager = roleManager;
_repo = repo;
_context = context;
}
public IActionResult Index()
{
List<RoleListViewModel> model = new List<RoleListViewModel>();
model = _roleManager.Roles.Select(r => new RoleListViewModel
{
RoleName = r.Name,
Description = r.Description,
Id = r.Id,
NumberOfUsers = r.UserRoles.Count
}).ToList();
return View(model);
}
[AutoValidateAntiforgeryToken]
public ActionResult Details(string id)
{
var role = _repo.GetRole((string)id);
if (role == null)
{
return RedirectToAction("Index");
}
return View(role);
}
[HttpGet]
public IActionResult Create()
{
return View();
}
[AutoValidateAntiforgeryToken]
[HttpPost]
public async Task<IActionResult> Create(RoleViewModel vm)
{
if (!ModelState.IsValid)
return View(vm);
{
var role = new ApplicationRole
{ Name = vm.Name };
var result = await _roleManager.CreateAsync(role);
if (result.Succeeded)
{
_repo.AddRole(role);
return RedirectToAction("Index");
}
else
foreach (var error in result.Errors)
{
ModelState.AddModelError("", error.Description);
}
return View(vm);
}
}
[HttpGet]
public ActionResult Delete(string Id)
{
var role = _context.Roles.Find(Id);
if (role == null)
{
return RedirectToAction("Index");
}
return View(role);
}
[ValidateAntiForgeryToken]
[HttpPost]
public async Task<ActionResult> Delete([Bind(include: "Id,Name")]ApplicationRole myRole)
{
ApplicationRole role = _context.Roles.Find(myRole.Id);
_context.Roles.Remove(role);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
[HttpGet]
public IActionResult Edit(string Id)
{
var role = _repo.GetRole((string)Id);
if (role == null)
{
return RedirectToAction("Index");
}
return View(new RoleViewModel { Id = role.Id, Name = role.Name, Description = role.Description });
}
[HttpPost]
public async Task<IActionResult> Edit(RoleViewModel vm)
{
var role = await _roleManager.FindByIdAsync(vm.Id);
if (vm.Name != role.Name)
{
role.Name = vm.Name;
}
if(vm.Description != role.Description)
{
role.Description = vm.Description;
}
var result = _roleManager.UpdateAsync(role).Result;
if (result.Succeeded)
{
return RedirectToAction("Index", "Roles");
}
else return View(vm);
}
//[HttpGet]
//public async Task<IActionResult> AssignRole(string Id)
//{
// List<UserRolesViewModel> model = new List<UserRolesViewModel>();
// model = _userManager.Users.Select(r => new UserRolesViewModel
// {
// Email = u.Email,
// Description = r.Description,
// Id = r.Id,
// NumberOfUsers = r.UserRoles.Count
// }).ToList();
// return View(model);
//}`
ApplicationUser.cs:
public class ApplicationUser : IdentityUser
{
public string FirstName { get; internal set; }
public string LastName { get; internal set; }
public virtual ICollection<IdentityUserClaim<string>> Claims { get; set; }
public virtual ICollection<IdentityUserLogin<string>> Logins { get; set; }
public virtual ICollection<IdentityUserToken<string>> Tokens { get; set; }
public virtual IEnumerable<ApplicationRole> Roles { get; set; }
public ICollection<ApplicationUserRole> UserRoles { get; set; }
public ICollection<MainComment> MainComments { get; set; }
}
ApplicationUserRole.cs
public class ApplicationUserRole : IdentityUserRole<string>
{
public virtual ApplicationUser User { get; set; }
public virtual ApplicationRole Role { get; set; }
}
ApplicationRole.cs
public class ApplicationRole : IdentityRole
{
public ApplicationRole() : base() { }
public ApplicationRole(string name)
: base(name)
{ }
public virtual ICollection<ApplicationUserRole> UserRoles { get; set; }
public string Description { get; set; }
}
这绝不是做这件事或做任何事情的正确方法。
不久前我做了一个角色分配器,这就是我想出的。
也无法分配 "Admin" 角色。可以简单的注释out/removed。和 class:
HomebreModel
只包含字符串
“分配”视图显示两个下拉列表,一个用于用户,另一个用于角色。
控制器
[Authorize(AuthenticationSchemes = HomebrewModel.BothAuthSchemes, Roles = HomebrewModel.RoleAdmin)]
public class RoleController : Controller
{
private readonly RoleManager<IdentityRole> _roleManager;
private readonly UserManager<NutricionUser> _userManager;
public RoleController(RoleManager<IdentityRole> roleManager, UserManager<NutricionUser> userManager)
{
_roleManager = roleManager;
_userManager = userManager;
}
// GET: Role
public async Task<ActionResult> Index()
{
var adminRole = await _roleManager.FindByNameAsync(HomebrewModel.RoleAdmin);
var assignableRoles = _roleManager.Roles.ToList();
assignableRoles.RemoveAt(assignableRoles.IndexOf(adminRole));
return View(assignableRoles);
}
// GET: Role/Assign
public async Task<ActionResult> Assign()
{
var adminRole = await _roleManager.FindByNameAsync(HomebrewModel.RoleAdmin);
var assignableRoles = _roleManager.Roles.ToList();
assignableRoles.RemoveAt(assignableRoles.IndexOf(adminRole));
ViewData["Name"] = new SelectList(assignableRoles, "Name", "Name");
ViewData["UserName"] = new SelectList(_userManager.Users, "UserName", "UserName");
return View(new RoleModel());
}
// POST: Role/Assign
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Assign(RoleModel roleModel)
{
if (ModelState.IsValid)
{
if(roleModel.Name == HomebrewModel.RoleAdmin)
{
ViewData["Message"] = "Invalid Request.";
return View("Info");
}
var user = await _userManager.FindByEmailAsync(roleModel.UserName);
if (user != null)
{
if (await _roleManager.RoleExistsAsync(roleModel.Name))
{
if(await _userManager.IsInRoleAsync(user, roleModel.Name))
{
ViewData["Message"] = $@"User {roleModel.UserName} already has the {roleModel.Name} role.";
return View("Info");
}
else
{
await _userManager.AddToRoleAsync(user, roleModel.Name);
ViewData["Message"] = $@"User {roleModel.UserName} was assigned the {roleModel.Name} role.";
return View("Info");
}
}
else
{
ViewData["Message"] = "Invalid Request.";
return View("Info");
}
}
else
{
ViewData["Message"] = "Invalid Request.";
return View("Info");
}
}
return View(roleModel);
}
}
这些是观点。
索引
@{
ViewData["Title"] = "Roles";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Roles</h2>
<p>
<a asp-action="Assign">Assign</a>
</p>
<table class="table">
<thead>
<tr>
<th>
Roles
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@item.Name
</td>
</tr>
}
</tbody>
</table>
分配
@model Models.RoleModel
@{
ViewData["Title"] = "Assign";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Assign</h2>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Assign">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Name" class="control-label"></label>
<select asp-for="Name" asp-items="(SelectList)@ViewData["Name"]"></select>
</div>
<div class="form-group">
<label asp-for="UserName" class="control-label"></label>
<select asp-for="UserName" asp-items="(SelectList)@ViewData["UserName"]"></select>
</div>
<div class="form-group">
<input type="submit" value="Assign" class="btn btn-default" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to list.</a>
</div>
这就是 RoleModel class
public class RoleModel
{
[Display(Name = "Name")]
public string Name { get; set; }
[Display(Name = "UserName")]
public string UserName { get; set; }
}
还有信息视图
@{
ViewData["Title"] = "Info";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Info</h2>
<h3>@ViewData["Message"]</h3>
如果要在 MVC 中为用户分配角色(在 asp.net 核心 2.1 中测试),您可以执行以下操作。我在这里也创建了一个用户,只是为了展示 UserManager 的注入。
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
namespace MyApp.Controllers
{
public class RolesController : Controller
{
private readonly RoleManager<IdentityRole> _roleManager;
private readonly UserManager<IdentityUser> _userManager;
public RolesController(RoleManager<IdentityRole> roleManager, UserManager<IdentityUser> userManager)
{
_roleManager = roleManager;
_userManager = userManager;
}
[HttpPost]
public async Task<IActionResult> AssignRoleToUser(string _roleName, string _userName)
{
//Created a user
var user = new IdentityUser { UserName = _userName, Email = "xyz@somedomain.tld" };
var result = await _userManager.CreateAsync(user, "[SomePassword]");
if (result.Succeeded)
{
// assign an existing role to the newly created user
await _userManager.AddToRoleAsync(user, "Admin");
}
return View();
}
}
}
我正在尝试研究如何使用 ASP.Net 核心 2.1 在我的 Web 应用程序的管理界面中为用户分配角色。
我还没有找到答案。我的应用程序用户 ID 是基于字符串的,而不是整数。
目前我可以编辑用户、添加新用户、添加新角色删除角色、编辑角色名称,但无法为用户分配角色。
理想情况下,我想要做的是有一个视图,它有两个下拉列表。一个包含所有用户以及我可以分配的可用角色列表。
有没有人有任何关于如何实现这一目标的提示?
这是我当前的角色控制器。对于上下文,我使用的是存储库模式。并实现了一些身份模型、ApplicationUser、ApplicationUserRole 和 Application Role。
角色controller.cs:
[Authorize(Roles = "Admin")]
public class RolesController : Controller
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly RoleManager<ApplicationRole> _roleManager;
private IRepository _repo;
private readonly ApplicationDbContext _context;
public RolesController(UserManager<ApplicationUser> userManager,
RoleManager<ApplicationRole> roleManager, IRepository repo, ApplicationDbContext context)
{
_userManager = userManager;
_roleManager = roleManager;
_repo = repo;
_context = context;
}
public IActionResult Index()
{
List<RoleListViewModel> model = new List<RoleListViewModel>();
model = _roleManager.Roles.Select(r => new RoleListViewModel
{
RoleName = r.Name,
Description = r.Description,
Id = r.Id,
NumberOfUsers = r.UserRoles.Count
}).ToList();
return View(model);
}
[AutoValidateAntiforgeryToken]
public ActionResult Details(string id)
{
var role = _repo.GetRole((string)id);
if (role == null)
{
return RedirectToAction("Index");
}
return View(role);
}
[HttpGet]
public IActionResult Create()
{
return View();
}
[AutoValidateAntiforgeryToken]
[HttpPost]
public async Task<IActionResult> Create(RoleViewModel vm)
{
if (!ModelState.IsValid)
return View(vm);
{
var role = new ApplicationRole
{ Name = vm.Name };
var result = await _roleManager.CreateAsync(role);
if (result.Succeeded)
{
_repo.AddRole(role);
return RedirectToAction("Index");
}
else
foreach (var error in result.Errors)
{
ModelState.AddModelError("", error.Description);
}
return View(vm);
}
}
[HttpGet]
public ActionResult Delete(string Id)
{
var role = _context.Roles.Find(Id);
if (role == null)
{
return RedirectToAction("Index");
}
return View(role);
}
[ValidateAntiForgeryToken]
[HttpPost]
public async Task<ActionResult> Delete([Bind(include: "Id,Name")]ApplicationRole myRole)
{
ApplicationRole role = _context.Roles.Find(myRole.Id);
_context.Roles.Remove(role);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
[HttpGet]
public IActionResult Edit(string Id)
{
var role = _repo.GetRole((string)Id);
if (role == null)
{
return RedirectToAction("Index");
}
return View(new RoleViewModel { Id = role.Id, Name = role.Name, Description = role.Description });
}
[HttpPost]
public async Task<IActionResult> Edit(RoleViewModel vm)
{
var role = await _roleManager.FindByIdAsync(vm.Id);
if (vm.Name != role.Name)
{
role.Name = vm.Name;
}
if(vm.Description != role.Description)
{
role.Description = vm.Description;
}
var result = _roleManager.UpdateAsync(role).Result;
if (result.Succeeded)
{
return RedirectToAction("Index", "Roles");
}
else return View(vm);
}
//[HttpGet]
//public async Task<IActionResult> AssignRole(string Id)
//{
// List<UserRolesViewModel> model = new List<UserRolesViewModel>();
// model = _userManager.Users.Select(r => new UserRolesViewModel
// {
// Email = u.Email,
// Description = r.Description,
// Id = r.Id,
// NumberOfUsers = r.UserRoles.Count
// }).ToList();
// return View(model);
//}`
ApplicationUser.cs:
public class ApplicationUser : IdentityUser
{
public string FirstName { get; internal set; }
public string LastName { get; internal set; }
public virtual ICollection<IdentityUserClaim<string>> Claims { get; set; }
public virtual ICollection<IdentityUserLogin<string>> Logins { get; set; }
public virtual ICollection<IdentityUserToken<string>> Tokens { get; set; }
public virtual IEnumerable<ApplicationRole> Roles { get; set; }
public ICollection<ApplicationUserRole> UserRoles { get; set; }
public ICollection<MainComment> MainComments { get; set; }
}
ApplicationUserRole.cs
public class ApplicationUserRole : IdentityUserRole<string>
{
public virtual ApplicationUser User { get; set; }
public virtual ApplicationRole Role { get; set; }
}
ApplicationRole.cs
public class ApplicationRole : IdentityRole
{
public ApplicationRole() : base() { }
public ApplicationRole(string name)
: base(name)
{ }
public virtual ICollection<ApplicationUserRole> UserRoles { get; set; }
public string Description { get; set; }
}
这绝不是做这件事或做任何事情的正确方法。
不久前我做了一个角色分配器,这就是我想出的。
也无法分配 "Admin" 角色。可以简单的注释out/removed。和 class:
HomebreModel
只包含字符串
“分配”视图显示两个下拉列表,一个用于用户,另一个用于角色。
控制器
[Authorize(AuthenticationSchemes = HomebrewModel.BothAuthSchemes, Roles = HomebrewModel.RoleAdmin)]
public class RoleController : Controller
{
private readonly RoleManager<IdentityRole> _roleManager;
private readonly UserManager<NutricionUser> _userManager;
public RoleController(RoleManager<IdentityRole> roleManager, UserManager<NutricionUser> userManager)
{
_roleManager = roleManager;
_userManager = userManager;
}
// GET: Role
public async Task<ActionResult> Index()
{
var adminRole = await _roleManager.FindByNameAsync(HomebrewModel.RoleAdmin);
var assignableRoles = _roleManager.Roles.ToList();
assignableRoles.RemoveAt(assignableRoles.IndexOf(adminRole));
return View(assignableRoles);
}
// GET: Role/Assign
public async Task<ActionResult> Assign()
{
var adminRole = await _roleManager.FindByNameAsync(HomebrewModel.RoleAdmin);
var assignableRoles = _roleManager.Roles.ToList();
assignableRoles.RemoveAt(assignableRoles.IndexOf(adminRole));
ViewData["Name"] = new SelectList(assignableRoles, "Name", "Name");
ViewData["UserName"] = new SelectList(_userManager.Users, "UserName", "UserName");
return View(new RoleModel());
}
// POST: Role/Assign
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Assign(RoleModel roleModel)
{
if (ModelState.IsValid)
{
if(roleModel.Name == HomebrewModel.RoleAdmin)
{
ViewData["Message"] = "Invalid Request.";
return View("Info");
}
var user = await _userManager.FindByEmailAsync(roleModel.UserName);
if (user != null)
{
if (await _roleManager.RoleExistsAsync(roleModel.Name))
{
if(await _userManager.IsInRoleAsync(user, roleModel.Name))
{
ViewData["Message"] = $@"User {roleModel.UserName} already has the {roleModel.Name} role.";
return View("Info");
}
else
{
await _userManager.AddToRoleAsync(user, roleModel.Name);
ViewData["Message"] = $@"User {roleModel.UserName} was assigned the {roleModel.Name} role.";
return View("Info");
}
}
else
{
ViewData["Message"] = "Invalid Request.";
return View("Info");
}
}
else
{
ViewData["Message"] = "Invalid Request.";
return View("Info");
}
}
return View(roleModel);
}
}
这些是观点。
索引
@{
ViewData["Title"] = "Roles";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Roles</h2>
<p>
<a asp-action="Assign">Assign</a>
</p>
<table class="table">
<thead>
<tr>
<th>
Roles
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@item.Name
</td>
</tr>
}
</tbody>
</table>
分配
@model Models.RoleModel
@{
ViewData["Title"] = "Assign";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Assign</h2>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Assign">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Name" class="control-label"></label>
<select asp-for="Name" asp-items="(SelectList)@ViewData["Name"]"></select>
</div>
<div class="form-group">
<label asp-for="UserName" class="control-label"></label>
<select asp-for="UserName" asp-items="(SelectList)@ViewData["UserName"]"></select>
</div>
<div class="form-group">
<input type="submit" value="Assign" class="btn btn-default" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to list.</a>
</div>
这就是 RoleModel class
public class RoleModel
{
[Display(Name = "Name")]
public string Name { get; set; }
[Display(Name = "UserName")]
public string UserName { get; set; }
}
还有信息视图
@{
ViewData["Title"] = "Info";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Info</h2>
<h3>@ViewData["Message"]</h3>
如果要在 MVC 中为用户分配角色(在 asp.net 核心 2.1 中测试),您可以执行以下操作。我在这里也创建了一个用户,只是为了展示 UserManager 的注入。
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
namespace MyApp.Controllers
{
public class RolesController : Controller
{
private readonly RoleManager<IdentityRole> _roleManager;
private readonly UserManager<IdentityUser> _userManager;
public RolesController(RoleManager<IdentityRole> roleManager, UserManager<IdentityUser> userManager)
{
_roleManager = roleManager;
_userManager = userManager;
}
[HttpPost]
public async Task<IActionResult> AssignRoleToUser(string _roleName, string _userName)
{
//Created a user
var user = new IdentityUser { UserName = _userName, Email = "xyz@somedomain.tld" };
var result = await _userManager.CreateAsync(user, "[SomePassword]");
if (result.Succeeded)
{
// assign an existing role to the newly created user
await _userManager.AddToRoleAsync(user, "Admin");
}
return View();
}
}
}