2017-06-12 25 views
0

数か月前、私はASP.NET Identityの独自の実装を作成し、UserStoreをオーバーライドして、Entity Frameworkの代わりにdapperとカスタムSQL接続を使用しました。当時はうまくいきました。ASP.NET IDがあります。UserManager.CreateAsync()は最近更新された変更で更新されましたか?

今、私は今日のすべてのナゲットパッケージを更新して以来、私は問題と戦ってきました。私はvar result = await UserManager.CreateAsync(user, newAccount.Password);を呼び出すことで、新規ユーザーを登録する際、主には、ユーザーが作成され、他のすべてのチェックがうまく行ったが、その後UserManager.CreateAsyncを上書きする必要が新しい方法を持っているかのようInvalid operation. The connection is closed.

そのことを言っ奇妙なエラーをスローします私はそれが何であるか全く分かりません。

アカウント・コントローラ:

 [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();がありました。接続がクローズされたというエラーに関する複数のスレッドから。この行がなくても、クエリは正常に動作し、新しいユーザーがデータベースに正しく挿入されます。

UserManager.CreateAsync()によってUserStore.CreateAsync()が呼び出された後、どこかでエラーが発生しています。

何が不足していますか?

答えて

0

答えはいいえ、ASP.NET IDは変更を加えて変更されていません。

DotNetPeekを使用して、UserManager.CreateAsync()の実行中に呼び出されたメソッドを確認するためにIdentityライブラリを調べ、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); 
    } 
} 

これは今後、他の誰かが同じ種類の問題に直面するのに役立ちます。

関連する問題