CreateUserIdenityAsync返回自定义IdentityUser的“UserId not found”exception

我正在关注使用JWT创建基于身份和角色的声明的bitoftech教程 。 我的应用程序用户是一个带有int PK的自定义User表。

目前,GenerateUserIdentityAsync方法只返回一个奇怪的UserId not found错误。 这是我的代码:

 ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, "JWT"); 

User实体中的实现:

 public async Task GenerateUserIdentityAsync(UserManager manager, string authenticationType) { //error on this line: CreateIdentityAsync throws error var userIdentity = await manager.CreateIdentityAsync(this, authenticationType); return userIdentity; } 

我的UserManager类定义如下:

 public class AppUserManager : UserManager 

奇怪的是,当我调试时, GenerateIdentityAsync中的实例确实有一个UserId属性,但是只有一个id ,我想知道这是不是错误的地方? (听起来不对)

我正在查看源代码 (第80行),但我无法弄清楚exception被抛出的位置。

抛出的确切exception是:

  UserId not found. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: System.InvalidOperationException: UserId not found. 

堆栈跟踪并不是那么有用(对我而言)

如何找出UserId不可用的原因/位置?


模式细节:

我的GrantResourceOwnerCredentials()

 public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] {"*"}); var userManager = context.OwinContext.GetUserManager(); User user = await userManager.FindAsync(context.UserName, context.Password); if (user == null) // this is NOT null { context.SetError("invalid_grant", "The username or password is incorrect"); return; } // this line fails ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, "JWT"); var ticket = new AuthenticationTicket(oAuthIdentity, null); context.Validated(ticket); } 

ApplicationUser (在我的例子中,只是User

 public partial class User : IdentityUser { public int UserId { get; set; } public string Fullname { get; set; } public string Address { get; set; } public string ContactNumber { get; set; } } 

正如您在调试时发现的那样, IdentityUser有一个Id ,在您的情况下,它代表用户的ID。

您需要从User类中删除UserId ,使用IdentityUser的基本Id并将自定义User表中的UserId列重命名为Id

您的User类中的任何属性都需要在数据库的用户表中具有匹配的列。 如果没有,那么对于不匹配的属性,您将得到相同的错误。

这意味着FullnameAddressContactNumber必须在AspNetUsers表中具有匹配的列名,否则您也将获得这些属性的相同错误。

您的ApplicationUser类是什么样的? 这个方法在你的应用程序中是什么样的?

 public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context){} 

Taiseer对GrantResourceOwnerCredentials的评论是:

“我们正在为登录用户构建身份,此身份将包含经过身份validation的用户的所有角色和声明”

我必须将ClaimsTypes.NameIdentifier添加到ClaimsIdentity以解决类似的问题。 以下是我的GrantResourceOwnerCredentials方法的重要部分:

 ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password); if (user == null) { context.SetError("invalid_grant", "The user name or password is incorrect."); return; } var identity = new ClaimsIdentity(context.Options.AuthenticationType); identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString())); 

您的User类中同时具有UserIdId属性 – Idinheritance自IdentityUser 。 问题是您可能将UserId配置为User的主键。

您获得的exception将在第97行 UserManager.GetSecurityStampAsync ClaimsIdentityFactory.CreateAsync方法中引发。 如您所见, user.Id用于检索安全戳。

如果您查看UserManager.GetSecurityStampAsync您将看到您获得的exception正好在这里抛出:

 public virtual async Task GetSecurityStampAsync(TKey userId) { ThrowIfDisposed(); var securityStore = GetSecurityStore(); var user = await FindByIdAsync(userId).WithCurrentCulture(); if (user == null) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Resources.UserIdNotFound, userId)); } return await securityStore.GetSecurityStampAsync(user).WithCurrentCulture(); } 

因此,从User类中删除UserId属性并开始使用Id (inheritance自IdentityUser )。

我遇到了完全相同的问题。 经过一段时间的痛苦,我可以解决真正的问题。 当您将User类的Id属性的数据类型更改为string时,将Guid()。ToString()分配给构造函数中的Id属性,并将相同的值保存到数据库,Identity将使用该值检索用户详细信息。

但是,如果您将Id属性的数据类型更改为int并且未在构造函数中为该属性提供值,则Identity仍会尝试使用默认的int值(0)来检索用户详细信息,这会导致抛出消息“System.InvalidOperationException:找不到UserId”。

我通过command.ExecuteScalar()从数据库中检索值来解决这个问题,并将值赋给user.Id. 希望这会帮助一些人面临类似的问题。

Server = xxxx;初始目录= xxxx ;; 用户ID = xxxx_user;密码= xxxx; 其中user id在其中有空格而不是Server = xxxx; Initial Catalog = xxxx ;; UserID = xxxx_user;密码= xxxx; 错误!!!!!!! 请参阅https://www.connectionstrings.com/sql-azure/进行确认。