使用Microsoft Identity调用PasswordSignInAsync抛出ArgumentNullException如何解决
异常原因
从异常栈可以判断,错误触发在ASP.NET Core Identity构造登录用户的Claims身份票据阶段:UserClaimsPrincipalFactory执行GenerateClaimsAsync方法生成用户标准Claim时,调用Claim类的构造函数传入了null作为value参数,而Claim类不允许声明值为空,因此抛出ArgumentNullException。
常见触发场景:
- 你登录使用的用户记录中,
Email、UserName、Id这类Identity默认会取来生成Claim的核心字段存在null值,其中Email字段为空是最高发的情况(如果你关闭了Identity的邮箱必填校验,创建用户时未给邮箱赋值就会出现该问题) - 你自定义了
IdentityUser的派生类,并且重写了UserClaimsPrincipalFactory的GenerateClaimsAsync方法,尝试将值为null的自定义字段加入用户Claim列表
修复方案
- 排查用户表字段:登录数据库查询当前测试用户的记录,检查
Email、UserName、Id字段是否为空。如果业务允许用户不填邮箱,可以给空邮箱的用户设置默认空字符串,或者在Identity配置中关闭邮箱Claim的生成。 - 检查自定义Claim逻辑:如果你重写了用户Claim生成逻辑,对所有作为Claim值的字段做空值兜底,示例如下:
// 错误写法:字段为null时直接抛出异常 claims.Add(new Claim("Avatar", user.Avatar)); // 正确写法:空值兜底处理 claims.Add(new Claim("Avatar", user.Avatar ?? string.Empty));
- 快速定位问题字段:可以在调用
PasswordSignInAsync之前加入调试代码,快速定位哪个字段为空:
// 调试用代码,哪一行抛出异常就对应哪个字段为空 var testClaim1 = new Claim(ClaimTypes.NameIdentifier, user.Id); var testClaim2 = new Claim(ClaimTypes.Name, user.UserName); var testClaim3 = new Claim(ClaimTypes.Email, user.Email); // 如果你有自定义Claim也依次加在这里测试
内容的提问来源于stack exchange,提问作者user
相关产品推荐
相关产品推荐

