簡體   English   中英

ASP.NET Identity UserManager.CreateAsync()最近是否已進行重大更改更新?

[英]Has ASP.NET Identity UserManager.CreateAsync() been updated with breaking changes recently?

幾個月前,我創建了自己的ASP.NET Identity實現,重寫了UserStore以使用dapper和自定義sql連接而不是Entity Framework。 當時效果很好。

現在,我今天更新了所有的nuget軟件包,從那以后我一直在解決問題。 主要是當我通過調用var result = await UserManager.CreateAsync(user, newAccount.Password);注冊新用戶時var result = await UserManager.CreateAsync(user, newAccount.Password); 它會創建用戶並執行所有其他檢查,但是會引發一個奇怪的錯誤,提示“ Invalid operation. The connection is closed. 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(); 因為這是來自多個線程的關於連接關閉錯誤的建議。 即使沒有這一行,查詢也可以正常工作,並將新用戶正確插入數據庫中。

該錯誤來自UserManager.CreateAsync()調用UserStore.CreateAsync()之后的某個地方。

知道缺少什么嗎?

答案是否定的,ASP.NET Identity並未因重大更改而改變。

使用DotNetPeek,我查看了身份庫,以查看在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);
    }
}

希望這將有助於將來其他人遇到同樣的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM