ASP.NET MVC Identity Framework 在开发中挂起 FindByEmail 调用,但不是实时版本
ASP.NET MVC Identity Framework hangs on FindByEmail call in development, but not live version
我们的网站使用 MVC 和身份框架 2.0。在现场(幸运的是)用户现在可以完美登录:
这是使这项工作附加到 Account 控制器的 Login 操作的代码:
public async Task<ActionResult> Login(vmAccountLogin model, string ReturnUrl)
{
// if problems with model, just redisplay form
if (!ModelState.IsValid)
{
return View(model);
}
// hangs on this line
var user = UserManager.FindByEmail(model.Email);
// if user not found for this email, abort with no clues
if (user == null)
当我构建项目并将 DLL 复制到实时服务器时,它运行良好。但是...
在我的测试版本中,它挂在显示的行上。大约十秒钟后,调试跳转到 Dispose 方法。我逐行检查了 web.config 文件以检查它们是否相同。我读过很多 SO 文章,但认为它们都不适用于这个问题。顺便说一句,这是 UserManager 调用,它工作正常:
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
如果我启用 .NET 符号调试,它会挂在 FindByEmail 方法调用上。 GetUserManager 调用立即显示了这一点 window:
?HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
{wiseowl.ApplicationUserManager}
ClaimsIdentityFactory: {Microsoft.AspNet.Identity.ClaimsIdentityFactory<wiseowl.Models.ApplicationUser, string>}
DefaultAccountLockoutTimeSpan: {00:05:00}
EmailService: {wiseowl.EmailService}
MaxFailedAccessAttemptsBeforeLockout: 5
PasswordHasher: {Microsoft.AspNet.Identity.PasswordHasher}
PasswordValidator: {Microsoft.AspNet.Identity.PasswordValidator}
SmsService: {wiseowl.SmsService}
Store: {Microsoft.AspNet.Identity.EntityFramework.UserStore<wiseowl.Models.ApplicationUser>}
SupportsQueryableUsers: true
SupportsUserClaim: true
SupportsUserEmail: true
SupportsUserLockout: true
SupportsUserLogin: true
SupportsUserPassword: true
SupportsUserPhoneNumber: true
SupportsUserRole: true
SupportsUserSecurityStamp: true
SupportsUserTwoFactor: true
TwoFactorProviders: Count = 2
UserLockoutEnabledByDefault: true
UserTokenProvider: {Microsoft.AspNet.Identity.Owin.DataProtectorTokenProvider<wiseowl.Models.ApplicationUser>}
UserValidator: {Microsoft.AspNet.Identity.UserValidator<wiseowl.Models.ApplicationUser>}
Users: {System.Data.Entity.DbSet<wiseowl.Models.ApplicationUser>}
_claimsFactory: {Microsoft.AspNet.Identity.ClaimsIdentityFactory<wiseowl.Models.ApplicationUser, string>}
_defaultLockout: {00:05:00}
_disposed: false
_factors: Count = 2
_passwordHasher: {Microsoft.AspNet.Identity.PasswordHasher}
_passwordValidator: {Microsoft.AspNet.Identity.PasswordValidator}
_userValidator: {Microsoft.AspNet.Identity.UserValidator<wiseowl.Models.ApplicationUser>}
请问大家有什么建议吗?
到目前为止,测试环境中的挂起看起来像是异步和阻塞调用的混合,这可能会导致死锁。 FindByEmail
是一种扩展方法,它包装了 UserManager.FindByEmailAsync
.
的异步 API 调用
在 UserManagerExtensions.cs 中找到的该版本的源代码显示异步调用正在同步执行。
/// <summary>
/// Find a user by email
/// </summary>
/// <param name="manager"></param>
/// <param name="email"></param>
/// <returns></returns>
public static TUser FindByEmail<TUser, TKey>(this UserManager<TUser, TKey> manager, string email)
where TKey : IEquatable<TKey>
where TUser : class, IUser<TKey>
{
if (manager == null)
{
throw new ArgumentNullException("manager");
}
return AsyncHelper.RunSync(() => manager.FindByEmailAsync(email));
}
我认为在测试环境中 运行 时会导致死锁(挂起)。没有解释为什么它仍然在实时环境中工作。
我建议按照预期通过 FindByEmailAsync
方法使代码一直异步。尽量避免混合异步和阻塞调用。
public async Task<ActionResult> Login(vmAccountLogin model, string ReturnUrl) {
// if problems with model, just redisplay form
if (!ModelState.IsValid) {
return View(model);
}
// hangs on this line
var user = await UserManager.FindByEmailAsync(model.Email);
// if user not found for this email, abort with no clues
if (user == null)
//...code removed for brevity
除此之外,我还建议确保测试环境为身份数据存储使用正确的连接字符串。由于挂起也可能是由于等待连接到数据库时超时。
我们的网站使用 MVC 和身份框架 2.0。在现场(幸运的是)用户现在可以完美登录:
这是使这项工作附加到 Account 控制器的 Login 操作的代码:
public async Task<ActionResult> Login(vmAccountLogin model, string ReturnUrl)
{
// if problems with model, just redisplay form
if (!ModelState.IsValid)
{
return View(model);
}
// hangs on this line
var user = UserManager.FindByEmail(model.Email);
// if user not found for this email, abort with no clues
if (user == null)
当我构建项目并将 DLL 复制到实时服务器时,它运行良好。但是...
在我的测试版本中,它挂在显示的行上。大约十秒钟后,调试跳转到 Dispose 方法。我逐行检查了 web.config 文件以检查它们是否相同。我读过很多 SO 文章,但认为它们都不适用于这个问题。顺便说一句,这是 UserManager 调用,它工作正常:
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
如果我启用 .NET 符号调试,它会挂在 FindByEmail 方法调用上。 GetUserManager 调用立即显示了这一点 window:
?HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
{wiseowl.ApplicationUserManager}
ClaimsIdentityFactory: {Microsoft.AspNet.Identity.ClaimsIdentityFactory<wiseowl.Models.ApplicationUser, string>}
DefaultAccountLockoutTimeSpan: {00:05:00}
EmailService: {wiseowl.EmailService}
MaxFailedAccessAttemptsBeforeLockout: 5
PasswordHasher: {Microsoft.AspNet.Identity.PasswordHasher}
PasswordValidator: {Microsoft.AspNet.Identity.PasswordValidator}
SmsService: {wiseowl.SmsService}
Store: {Microsoft.AspNet.Identity.EntityFramework.UserStore<wiseowl.Models.ApplicationUser>}
SupportsQueryableUsers: true
SupportsUserClaim: true
SupportsUserEmail: true
SupportsUserLockout: true
SupportsUserLogin: true
SupportsUserPassword: true
SupportsUserPhoneNumber: true
SupportsUserRole: true
SupportsUserSecurityStamp: true
SupportsUserTwoFactor: true
TwoFactorProviders: Count = 2
UserLockoutEnabledByDefault: true
UserTokenProvider: {Microsoft.AspNet.Identity.Owin.DataProtectorTokenProvider<wiseowl.Models.ApplicationUser>}
UserValidator: {Microsoft.AspNet.Identity.UserValidator<wiseowl.Models.ApplicationUser>}
Users: {System.Data.Entity.DbSet<wiseowl.Models.ApplicationUser>}
_claimsFactory: {Microsoft.AspNet.Identity.ClaimsIdentityFactory<wiseowl.Models.ApplicationUser, string>}
_defaultLockout: {00:05:00}
_disposed: false
_factors: Count = 2
_passwordHasher: {Microsoft.AspNet.Identity.PasswordHasher}
_passwordValidator: {Microsoft.AspNet.Identity.PasswordValidator}
_userValidator: {Microsoft.AspNet.Identity.UserValidator<wiseowl.Models.ApplicationUser>}
请问大家有什么建议吗?
到目前为止,测试环境中的挂起看起来像是异步和阻塞调用的混合,这可能会导致死锁。 FindByEmail
是一种扩展方法,它包装了 UserManager.FindByEmailAsync
.
在 UserManagerExtensions.cs 中找到的该版本的源代码显示异步调用正在同步执行。
/// <summary>
/// Find a user by email
/// </summary>
/// <param name="manager"></param>
/// <param name="email"></param>
/// <returns></returns>
public static TUser FindByEmail<TUser, TKey>(this UserManager<TUser, TKey> manager, string email)
where TKey : IEquatable<TKey>
where TUser : class, IUser<TKey>
{
if (manager == null)
{
throw new ArgumentNullException("manager");
}
return AsyncHelper.RunSync(() => manager.FindByEmailAsync(email));
}
我认为在测试环境中 运行 时会导致死锁(挂起)。没有解释为什么它仍然在实时环境中工作。
我建议按照预期通过 FindByEmailAsync
方法使代码一直异步。尽量避免混合异步和阻塞调用。
public async Task<ActionResult> Login(vmAccountLogin model, string ReturnUrl) {
// if problems with model, just redisplay form
if (!ModelState.IsValid) {
return View(model);
}
// hangs on this line
var user = await UserManager.FindByEmailAsync(model.Email);
// if user not found for this email, abort with no clues
if (user == null)
//...code removed for brevity
除此之外,我还建议确保测试环境为身份数据存储使用正确的连接字符串。由于挂起也可能是由于等待连接到数据库时超时。