先后ASP.NET身份UserManager.CreateAsync()已经用最近的重大更改更新?

问题描述:

几个月前,我创造了我自己的实现ASP.NET身份,覆盖UserStore使用短小精悍和自定义SQL连接,而不是实体框架。它在当时运行良好。先后ASP.NET身份UserManager.CreateAsync()已经用最近的重大更改更新?

现在我今天更新了所有的Nu​​Get包,因为我一直在争取的问题。主要是,当我通过调用var result = await UserManager.CreateAsync(user, newAccount.Password);它创建用户并执行所有其他检查就好了注册一个新用户,但随后抛出一个奇怪的错误说Invalid operation. The connection is closed.

它仿佛UserManager.CreateAsync有需要重写的新方法,但我完全不知道它会是什么。

仅供参考,这里有我的执行部分:

帐户控制:

 [Authorize] 
      public class AccountController : Controller 
      { 

       public UserManager<User> UserManager { get; private set; } 
       public UserTokenProvider UserTokenProvider { get; set; } 

       public AccountController() : this(new UserManager<User>(new UserStore(ConfigurationManager.ConnectionStrings["DBConn"].ConnectionString))) 
       { 
       } 

       public AccountController(UserManager<User> userManager) 
       { 
        UserManager = userManager; 
        UserManager.PasswordHasher = new NoPasswordHasher(); 

       } 

... 

     [HttpPost] 
     [AllowAnonymous] 
     [ValidateAntiForgeryToken] 
     public async Task<ActionResult> Register(RegistrationModel newAccount) 
     { 
      try 
      { 
       if (DbConfig.MaintenanceMode) return RedirectToAction("ComingSoon", "Home"); 
       if (ModelState.IsValid) 
       { 
        var user = new User(newAccount); 

        var result = await UserManager.CreateAsync(user, newAccount.Password); 
        if (result.Succeeded) 
        { 
         await SignInAsync(user, isPersistent: false); 
         var userIn = await UserManager.FindByEmailAsync(newAccount.UserName); 
         if (!userIn.EmailConfirmed) 
         { 
          await SendValidationEmail(userIn); 
          return RedirectToAction("ConfirmationSent", new {userName = user.UserName}); 
         } 
         return RedirectToAction("Index", "Home"); 
        } 
        else 
        { 
         AddErrors(result); 
        } 
       } 

       // If we got this far, something failed, redisplay form 
       return View(newAccount); 
      } 
      catch (Exception ex) 
      { 
       var msg = ex.Message; 

       return View(newAccount); 
      } 
     } 

用户存储:

public class UserStore : IUserStore<User>, IUserLoginStore<User>, IUserPasswordStore<User>, IUserSecurityStampStore<User>, IUserRoleStore<User>, IUserEmailStore<User> 
     { 
      private readonly string _dbConn; 


      public UserStore(string conn = null) 
      { 
       if (conn != null) 
        _dbConn = conn; 
       else 
        _dbConn = DbConfig.ConnectionString; 
      } 

      public void Dispose() 
      { 
      } 



      public virtual Task CreateAsync(User user) 
      { 
       using (var _conn = new SqlConnection(_dbConn)) 
       { 
        if (_conn.State == ConnectionState.Closed) _conn.Open(); 
        return _conn.ExecuteAsync("users_UserCreate", 
         new 
         { 
          @UserId = user.Id, 
          @UserName = user.UserName, 
          @PasswordHash = user.PasswordHash, 
          @SecurityStamp = user.SecurityStamp 
         }, commandType: CommandType.StoredProcedure); 

       } 
      } 

... Remaining methods omitted for brevity ... 

你会发现UserStore。 CreateAsync()函数有if (_conn.State == ConnectionState.Closed) _conn.Open();,因为这是建议从关于连接关闭错误的多个线程。即使没有这一行,查询也可以正常工作并将新用户正确插入数据库。

的错误是从什么地方来UserStore.CreateAsync后()由UserManager.CreateAsync()调用。

任何想法缺少什么?

答案是否定的,ASP.NET身份不破的变化改变。

使用DotNetPeek我查看了Identity库以查看在UserManager.CreateAsync()期间调用的方法,它只调用UserStore.CreateSync和密码更新。

在玩了一段代码之后,我发现虽然UserManager.CreateSync正在等待,但对UserStore.CreateSync的内部调用却没有。坦克必须重写public virtual Task CreateAsync(User user)并且不得不返回一个未等待的任务,我们必须耍一些代码来等待Dapper的响应,然后再将它作为任务的一部分返回。

所以,这里的更新UserStore.CreateAsync覆盖工程。注意:if (_conn.State == ConnectionState.Closed) _conn.Open();实际上并不需要,因为在方法结束之前连接已关闭,Dapper在为您处理连接方面做得非常出色。

public virtual Task CreateAsync(User user) 
{ 
    using (var _conn = new SqlConnection(_dbConn)) 
    { 
     var result = _conn.ExecuteAsync("users_UserCreate", new 
        { 
         @UserId = user.Id, 
         @UserName = user.UserName, 
         @PasswordHash = user.PasswordHash, 
         @SecurityStamp = user.SecurityStamp 
        }, commandType: CommandType.StoredProcedure).ConfigureAwait(true); 

     return Task.FromResult(result); 
    } 
} 

希望这会帮助别人在未来面临同样的问题。