igg*_*web 7 c# asp.net-mvc-5 asp.net-identity-2
出于某种原因,我还没有发现,但在注册和激活成功后,我无法使用电子邮件地址登录,而是收到错误"无效登录尝试".
由于使用电子邮件登录改进了ASP.NET Identity 2.0,我已经修改了注册表单以实际存储真实用户名,因为现有注册似乎通过将Username与电子邮件地址一起存储来复制.
请参阅下面Install-Package Microsoft.AspNet.Identity.Samples -Pre'创建空ASP.NET Web应用程序(MVC)项目后随附的标准代码:
var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
Run Code Online (Sandbox Code Playgroud)
我的功能现在如下:
var user = new ApplicationUser { TitleId = model.TitleId, SexId = model.SexId, Forename = model.Forename, Surname = model.Surname, UserName = model.UserName, Email = model.Email, JoinDate = System.DateTime.Now };
Run Code Online (Sandbox Code Playgroud)
如您所见,UserName现在从表单接收值.这一切都很好,除了现在我注册和激活后无法登录.唯一的工作是通过将电子邮件字段中的值放入UserName字段来修改记录,这似乎是愚蠢的.
有人可以告诉我可能错过了什么吗?
你必须修改SignInHelper.PasswordSignIn方法.默认情况下,它用于FindByNameAsync检查具有给定名称的用户是否存在:
public async Task<SignInStatus> PasswordSignIn(string userName, string password, bool isPersistent, bool shouldLockout)
{
var user = await UserManager.FindByNameAsync(userName);
// (...)
Run Code Online (Sandbox Code Playgroud)
改变它使用FindByEmailAsync:
var user = await UserManager.FindByEmailAsync(userName);
Run Code Online (Sandbox Code Playgroud)
您可以SignInHelper在*AppCode\IdentityConfig.cs`文件中找到类.
在类AccountController.cs 中,方法:public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)。修改了这个:
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
Run Code Online (Sandbox Code Playgroud)
对此:
try
{
var user = db.Users.Where(u => u.Email.Equals(model.Email)).Single(); // where db is ApplicationDbContext instance
var result = await SignInManager.PasswordSignInAsync(user.UserName, model.Password, model.RememberMe, shouldLockout: false);
}
catch (InvalidOperationException)
{
// the user is not exist
}
Run Code Online (Sandbox Code Playgroud)
原因是UserName和UserEmail具有不同的值,但方法PasswordSignInAsync仅用于UserName检查登录。
小智 8
我遇到了同样的问题,但发现解决方案是将 Marcin 接受的答案和 Hai 的答案结合起来。在AccountController.cs您需要使用FindByEmailAsync(), 而不是FindByNameAsync(),然后使用SignInManager.PasswordSignInAsync()但使用 的值user.UserName作为第一个参数(只要user不为空),而不是model.Email。所以一个完整的答案,基于当前的样板代码,应该是这样的:
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
// (...) ModelState.IsValid, etc
string user_name = ""; // in case 'user' is null (user not found)
var user = await UserManager.FindByEmailAsync(model.Email);
if (user != null)
{
user_name = user.UserName;
if (!await UserManager.IsEmailConfirmedAsync(user.Id))
{
// (...) Require the user to have a confirmed email before they can log on, etc
}
}
// don't use model.Email below, use the value from user.UserName (if user not null)
var result = await SignInManager.PasswordSignInAsync(user_name, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
// (...)
Run Code Online (Sandbox Code Playgroud)