将 ASP.Net 标识实体框架用于现有 AspNetUsers 表,其中 ID 列设置为唯一标识符

本文关键字:ID 其中 设置 标识符 唯一 AspNetUsers 标识 Net ASP 实体 框架 | 更新日期: 2023-09-27 18:37:08

我正在使用Nuget包Microsoft.AspNet.Identity.EntityFramework并连接到现有的SQL Server数据库,其中AspNetUsers table ID列设置为UniqueIdentifier。

执行调用以获取用户时,我收到错误:

"IdentityUser'4"上的"Id"属性不能设置为"System.Guid"值。必须将此属性设置为类型为"System.String"的非空值。

有没有办法在代码中设置 Id 属性,因为我无法修改数据库上的列属性。

以下是我的代码片段:

身份验证提供程序.cs

public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
  public override async Task GrantCredentials(OAuthGrantResourceOwnerCredentialsContext context)
  {
    using(Repository _repo = new Repository())
    {
      IdentityUser user = await _repo.FindUser(context.UName, context.PWord);
      if(user == null)
      {
        // User Not Found / Invalid UName or PWord.
      }
    }
  }
}

存储库.cs

public class Repository : IDisposable
{
  private AppContext _ctx;
  private UserManager<IdentityUser> _usrMgr;
  public Repository()
  {
    _ctx = new AppContext();
    _usrMgr = new UserManager<IdentityUser>(new UserStore<IdentityUser>(_ctx));
  }
  public async Task<IdentityUser> FindUser(string uName, string pWord)
  {
    // Setting the breakpoint here in this line below: 
    IdentityUser usr = await _usrMgr.FindAsync(uName, pWord);
    return user;
  }
}

在我在 Repository.cs 上设置的断点上,当我展开 _usrMgr 变量并检查 Users 属性时,我看到错误。

更新:我在这里找到了一些信息(在标题为的部分):

使主键的类型对用户和角色具有可扩展性

但我不确定如何正确实施这一点。我需要添加新类吗?我的理解中,那里的实现相当模糊。

将 ASP.Net 标识实体框架用于现有 AspNetUsers 表,其中 ID 列设置为唯一标识符

实际上,是的,您必须实现自己的IdentityUser类。默认情况下,在身份框架中IdentityUser id 的类型为 string ,这并不总是可接受的。因此,您可以执行以下操作:

public sealed class User : IdentityUser<int, UserLogin, UserRole, UserClaim>

其中int是用户 ID 的类型。如果你想使用你的自定义UserLoginUserRoleUserClaim(默认情况下它们的ID也是刺痛,所以你可能也想这样做),那么你必须添加你的自定义继承类:

public class UserRole : IdentityUserRole<int> { } //int is id type
public class UserClaim : IdentityUserClaim<int> { } //int is id type
public class UserLogin : IdentityUserLogin<int> { } //int is id type

接下来您要做的是使用由标识、管理器(如 UserManagerSignInManager)提供的所有自定义实体类:

public class ApplicationUserManager : UserManager<User, int> {}
public class ApplicationSignInManager : SignInManager<User, int> {}

其中User类型是自定义User : IdentityUser<int, UserLogin, UserRole, UserClaim>(如上所述),int是 ID 类型。因此,简而言之,基本思想是使用您自己的实现继承默认 Identity 类型,并在 Identity 使用其默认类型的地方使用它们。这是可以的做法。在您的情况下,我建议,UniqueIdentifier是某种自定义类型,因此您必须使用此类型而不是int(如您提供的示例):

public sealed class User : IdentityUser<UniqueIdentifier, UserLogin, UserRole, UserClaim>