【问题标题】:ASP.NET Identity 2.0 UserManager.FindByIdAsyc not returning RolesASP.NET Identity 2.0 UserManager.FindByIdAsyc 不返回角色
【发布时间】:2014-12-25 22:14:01
【问题描述】:

我正在使用 ASP.NET MVC v5.2、Entity Framework v6.0(代码优先)和 Identity 2.0 构建网站。

我的 UserAdmin 控制器中有以下代码:

    // GET: /UserAdmin/Details/5
    public async Task<ActionResult> Details(string id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }

        var user = await UserManager.FindByIdAsync(id);
        return View(user);
    }

我的问题是,虽然我可以使用 UserManager 填充用户的角色,但在使用 FindByIdAsync 方法时,它没有选择与该用户关联的角色

以下是 IdentityUserRole 表中的数据,该表显示了分配给两个角色的突出显示用户:

这是显示与上面相同的用户但角色计数为零的调试信息:

为什么没有返回该用户的角色?

编辑#1

我没有使用 UserManager 的默认实现。

我的 ApplicationUser 扩展了 IdentityUser 以允许我添加自定义属性。我的 ApplicationDbContext 扩展了 IdentityDbContext。

这里是我使用 Fluent API 为 Identity 设置主键的地方:

        modelBuilder.Entity<IdentityUserLogin>().HasKey<string>(l => l.UserId);
        modelBuilder.Entity<IdentityRole>().HasKey<string>(r => r.Id);
        modelBuilder.Entity<IdentityUserRole>().HasKey(r => new { r.RoleId, r.UserId });

【问题讨论】:

  • 您使用的是 UserManager、UserStore 等的默认实现吗?
  • a) 我可以看到您的IdentityUserRoleApplicationUser_IdIdentityRole_Id 列。他们不应该在那里。调整您的 DbContext 以删除这些列。 b) 当您从 DbContext 加载用户时,您需要专门加载角色 - 类似于:stackoverflow.com/a/26663667/809357
  • @Excommunicated 不,我的 ApplicationUser 使用自定义属性扩展了 IdentityUser。我的 ApplicationDBContext 还扩展了 IdentityDbContext。我正在通过 Fluent API 建立关系。
  • @trailmax 我不确定我的 DbContext 的哪一部分导致这两个额外的列存在。我在帖子中添加了一些代码,以展示我如何使用 Fluent API 设置密钥。
  • IdentityUserRole 长什么样子?

标签: asp.net asp.net-mvc entity-framework asp.net-identity roles


【解决方案1】:

当您扩展IdentityDbContextIdentityUser 时,您不需要为LoginsRolesUserRoles 定义您的关系,因为它们已经在基类中定义。您需要删除像modelBuilder.Entity&lt;IdentityUserRole&gt;().HasKey(r =&gt; new { r.RoleId, r.UserId }); 这样的行,因为它们已被处理。

至于不使用默认的UserManager 根据您提供的代码,我在这里看到了一种可能性。

UserManager 的默认实现将IUserStore&lt;TUser&gt; 作为其构造函数中的参数。如果您使用(或派生自)Microsoft.AspNet.Identity.EntityFramework 库中的UserStore&lt;TUser&gt; 实现,则角色、声明和登录等内容将包含在对数据库进行的查询中。如果您正在创建自己的实现IUserStore&lt;TUser&gt; 的类,那么您需要自己包含相关数据。下面是一个例子。

    public class ApplicationUser : IdentityUser
    {
        //Add your Custom Properties here..
    }

    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {

        //Add your Custom Properties here..
    }


    public class ApplicationUserStore : IUserStore<ApplicationUser>
    {
        private readonly ApplicationDbContext _context;

        public ApplicationUserStore(ApplicationDbContext context)
        {
            _context = context;
        }

        public async Task<ApplicationUser> FindByIdAsync(string userName)
        {
            return await _context.Users.Include(x => x.Roles).FirstOrDefaultAsync(n => n.UserName == userName);
        }
    }

【讨论】:

  • 为好信息干杯。检查它,如果它把它整理出来,将它标记为答案。除了删除 Fluent API 手动密钥设置之外,我还在按照 stackoverflow.com/a/19995982/242 测试在 OnModelCreating 中调用 base.OnModelCreating(modelBuilder);
猜你喜欢
  • 2016-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-13
  • 2016-10-24
  • 1970-01-01
  • 1970-01-01
  • 2014-10-28
相关资源
最近更新 更多