• 使用Asp.Net Core Identity给用户添加及删除角色


        基于Asp.Net Core编制一个项目,需要给用户添加及删除角色的功能,于是使用到了Identity中的UserManager。

        先后解决了几个问题,终于实现了设想。

    1. 环境条件

        Asp.Net Core 1.0.1

        Microsoft.AspNetCore.Identity.EntityFrameworkCore 1.0.0

    2. 给用户添加角色(组)使用到UserManager.AddToRolesAsync(),元数据中对AddToRolesAsync的解释为:

            //
            // 摘要:
            //     Add the specified user to the named roles.
            //
            // 参数:
            //   user:
            //     The user to add to the named roles.
            //
            //   roles:
            //     The name of the roles to add the user to.
            //
            // 返回结果:
            //     The System.Threading.Tasks.Task that represents the asynchronous operation, containing
            //     the Microsoft.AspNetCore.Identity.IdentityResult of the operation.
            [AsyncStateMachine(typeof(UserManager<>.<AddToRolesAsync>d__100))]
            public virtual Task<IdentityResult> AddToRolesAsync(TUser user, IEnumerable<string> roles);

        在我的代码中对应第一个参数的类型是AppcationUser,第二个参数应该是代表角色(组)的字符串列表;

        在controller中该行代码为:

    await _userManager.AddToRolesAsync(user, selectedRoles)

       在默认角色表中有两个关角色名的字段,一个是“Name”,另外一个是“NormalizedName”,如下图所示:

       

        经过尝试,AddToRolesAsync()中的第二个参数应该是“NormalizedName”。如果使用“Name”会出现错误。

    3. 删除用户已有角色会使用到UserManager.RemoveFromRoleAsync(),这个方法同样会使用到AddToRolesAsync()中的两个参数,使用方法与AddToRolesAsync()相同。

        但是,Identity提供的获取用户现有角色的方法只有:userManager.GetRolesAsync(user),其中参数“user”为<ApplicationUser>。

        这个方法的返回值从元数据中给出的解释是:role names。经过测试实际为“Name”字段。

            //
            // 摘要:
            //     Gets a list of role names the specified user belongs to.
            //
            // 参数:
            //   user:
            //     The user whose role names to retrieve.
            //
            // 返回结果:
            //     The System.Threading.Tasks.Task that represents the asynchronous operation, containing
            //     a list of role names.
            [AsyncStateMachine(typeof(UserManager<>.<GetRolesAsync>d__105))]
            public virtual Task<IList<string>> GetRolesAsync(TUser user);

        这样,就出现了不太方便的问题,删除用户角色方法RemoveFromRoleAsync(),需要使用“NormalizedName”,而identity获取的当前用户现有角色只能使用GetRolesAsync(),该方法获得的是角色的“Name”。

        所以想当然的代码(如下)不会出现编译错误,同样也不会出现运行错误,但实际运行后,应该被删除的角色实际上删除不了:

    var nowRoles = _userManager.GetRolesAsync(user).Result; //得到的nowRoles是角色的Name
    await _userManager.RemoveFromRolesAsync(user, nowRoles); //这里需要的是角色的NormalizedName

        所以,只能想办法得到当前用户角色的“NormalizedName”,再传递给RemoveFromRoleAsync()。

        这面这个办法比较繁琐,但想不到更简单的办法。

    var normalizedName = allRoles.Where(r => r.Name == nowRole).First().NormalizedName;

        其中:allRoles是这样得到的

    var allRoles = _roleManager.Roles;

        整个代码是这样的:

                    var allRoles = _roleManager.Roles; //系统中所有的角色
                    var nowRoles = _userManager.GetRolesAsync(user).Result; //该用户现有的角色“Name”
                    foreach (var nowRole in nowRoles)
                    {
                        var normalizedName = allRoles.Where(r => r.Name == nowRole).First().NormalizedName;//取得现有角色的NormalizedName
                        await _userManager.RemoveFromRoleAsync(user, normalizedName); //删除不要的角色
                    }
                    await _userManager.AddToRolesAsync(user, selectedRoles); //添加需要的角色
                    await _userManager.UpdateAsync(user); //完成储存

    上面代码没有进行针对性的添加,代码有些繁杂,不过这样也不会出现错误,省事儿。

    至此,结束。

    记录,备查。

  • 相关阅读:
    RECOVER DATABASE SKIP TABLESPACE
    mysql加解密函数
    node获取代码的svn版本号,并打包的时候,输出指定文件到打包后的项目里面
    layer.open iframe自动高度
    IIS部署.net5项目
    使用Windows命令行启动关闭服务(net,sc用法)(转)
    centos7 修改IP 设置静态IP,开启SSH
    链接PostgreSQL报错authentication method 10 not supported解决
    PostgreSQL Windows安装教程
    POI隐藏行 隐藏列,EasyExcel隐藏行 EasyExcel隐藏列
  • 原文地址:https://www.cnblogs.com/jqdy/p/6033683.html
Copyright © 2020-2023  润新知