【问题标题】:How to assign roles to users using the website interface in ASP.NET Core 2.1如何使用 ASP.NET Core 2.1 中的网站界面为用户分配角色
【发布时间】:2019-05-30 13:01:34
【问题描述】:

我正在尝试研究如何使用 ASP.Net core 2.1 在我的 Web 应用程序的管理界面中为用户分配角色。

我还没有找到答案。我的应用程序用户 ID 是基于字符串的,而不是整数。

目前我能够编辑用户、添加新用户、添加新角色、删除角色、编辑角色名称,但无法为用户分配角色。

理想情况下,我想做的是有一个视图,它有两个下拉列表。一个包含所有用户以及我可以分配的可用角色列表。

请问有没有人有关于如何实现这一点的提示?

这是我当前的角色控制器。对于上下文,我使用的是存储库模式。并且已经实现了一些身份模型,ApplicationUser、ApplicationUserRole 和 Application Role。

角色控制器.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; }  
}

【问题讨论】:

  • 代码格式为前缀4个空格。看起来你尝试使用直角括号,如果你想清理它。
  • 也许有关您的代码和代码结构的更多信息会对我们有所帮助。 :)

标签: c# asp.net-core asp.net-core-identity


【解决方案1】:

如果要在 MVC 中为用户分配角色(在 asp.net core 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();
        }

    }
}

【讨论】:

    【解决方案2】:

    这绝不是这样做或任何事情的正确方法。

    不久前我做了一个角色分配器,这就是我想出的。

    也不能分配“管理员”角色。它可以简单地注释掉/删除。和班级:

    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 类

    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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-05
      • 2019-07-10
      • 2010-10-30
      • 1970-01-01
      • 2020-10-16
      • 1970-01-01
      • 2015-06-10
      • 1970-01-01
      相关资源
      最近更新 更多