使用ASP.Net Identity EntityFramwork到现有的AspNetUsers表,ID列设置为UniqueIdentifier

Bat*_*uta 2 c# asp.net-identity

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

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

'IdentityUser`4'上的'Id'属性无法设置为'System.Guid'值.您必须将此属性设置为类型为"System.String"的非null值.

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

这是我的代码片段:

AuthProvider.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.
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

Repository.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;
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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

使用户和角色可以扩展主键类型

但我不确定如何正确实施这一点.我需要添加一个新课程吗?在我的理解中,那里的实施相当含糊.

Dmy*_*tro 5

实际上,是的,你必须实现自己的IdentityUser类.默认情况下,Identity Framework中的IdentityUserid是类型string,但并不总是可以接受.因此,您可以执行以下操作:

public sealed class User : IdentityUser<int, UserLogin, UserRole, UserClaim>
Run Code Online (Sandbox Code Playgroud)

哪里int是用户ID的类型.如果你想使用你的自定义UserLogin,UserRole或者UserClaim(默认情况下它们的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
Run Code Online (Sandbox Code Playgroud)

接下来你想要做的是使用由身份,管理员(如UserManagerSignInManager)提供的所有自定义实体类:

public class ApplicationUserManager : UserManager<User, int> {}
public class ApplicationSignInManager : SignInManager<User, int> {}
Run Code Online (Sandbox Code Playgroud)

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

public sealed class User : IdentityUser<UniqueIdentifier, UserLogin, UserRole, UserClaim>
Run Code Online (Sandbox Code Playgroud)