ASP标识角色不存在错误

时间:2016-06-22 13:13:13

标签: c# asp.net asp.net-mvc entity-framework .net-core

我正在尝试在我的MVC .NET CORE应用程序中创建一个页面,用户可以在其中更改其他用户的角色。此时视图和模型绑定都很有效,但是当实际尝试将角色保存回数据库时,我收到一条错误消息,指出角色不存在。我的方法是:

  1. 从模型中获取角色列表。
  2. 删除指定用户的现有角色。
  3. 使用模型中的列表添加角色。
  4. 如果出现错误,请在交易中执行此操作。
  5. 我在控制器中的代码如下:

                    var user = await _userManager.FindByIdAsync(id);
    
                    if (user == null)
                    {
                        return View("Error");
                    }
    
                    using (_context.Database.BeginTransaction())
                    {
                        var removeResult = await _userManager.RemoveFromRolesAsync(user, await _userManager.GetRolesAsync(user));
                        if (!removeResult.Succeeded)
                        {
                            return View("Error");
                        }
    
                        var addResult = await _userManager.AddToRolesAsync(user, model.MemberRoles);
                        if (!addResult.Succeeded)
                        {
                            return View("Error");
                        }
                    }
    

    其中model.MemberRolesList<string>个角色。奇怪的是,这个过程在_userManager.RemoveFromRolesAsync失败,即使我将用户的现有角色直接传递给函数。我试过放弃UserManager课程和ef一起去但没有运气。我还验证了模型中的角色与数据库中的角色匹配。是否有任何明显错误会导致失败?感谢。

    修改

    以下是我遇到的错误:

    InvalidOperationException: Role ADMINISTRATOR does not exist.
    Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`4.<AddToRoleAsync>d__32.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
    

    以下是我的数据库中定义的角色:

    enter image description here

2 个答案:

答案 0 :(得分:5)

当您尝试将用户添加到角色时,它首先尝试查找角色。在Sql Profiler中,您可以看到它实际上是通过NormalizedName字段而不是Name字段进行搜索。

exec sp_executesql N'
SELECT TOP(2) [r].[Id], [r].[ConcurrencyStamp], [r].[Name], [r].[NormalizedName]
FROM [AspNetRoles] AS [r]
WHERE [r].[NormalizedName] = @__normalizedRoleName_0',N'@__normalizedRoleName_0 nvarchar(256)',@__normalizedRoleName_0=N'ADMINISTRATOR'

解决方案是在创建角色时将NormalizedName字段设置为Name字段的大写:

所以在SeedData类中:

/* Create Roles */
IEnumerable<UserRole> allRoles = Enum.GetValues(typeof(UserRole)).Cast<UserRole>();


foreach (UserRole role in allRoles)
{
     if (!await roleManager.RoleExistsAsync(role.ToString()))
     {
                await roleManager.CreateAsync(new IdentityRole { 
                          Name = role.ToString(), 
                          NormalizedName = role.ToString().ToUpper() 
                        });
     }
}

答案 1 :(得分:2)

我真的很惊讶你没有得到InvalidCastException,因为无法直接将string[]投射到List<string>。我不确定你为什么一开始就这样做,因为如果你想要一个清单,你就可以轻松地拨打.ToList()而不是.ToArray(),并称之为一天。或者,由于GetRolesAsync的返回类型为IList<string>,无论如何,您甚至不需要这样做。现在,这是我看到你的代码唯一的问题。