先后ASP.NET身份UserManager.CreateAsync()已经用最近的重大更改更新?
几个月前,我创造了我自己的实现ASP.NET身份,覆盖UserStore使用短小精悍和自定义SQL连接,而不是实体框架。它在当时运行良好。先后ASP.NET身份UserManager.CreateAsync()已经用最近的重大更改更新?
现在我今天更新了所有的NuGet包,因为我一直在争取的问题。主要是,当我通过调用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);
}
}
希望这会帮助别人在未来面临同样的问题。