我在Identity 2.0 Samples之上构建了一个新应用程序,但我遇到了UsersAdmin / Edit问题。当应用程序回发到此页面时,行var result = UserManager,AddToRolesAsync(string userid, string[] roles)
会生成结果错误,指出已经采用了电子邮件地址。 “电子邮件somename@somedomain.com已被采用。”使用result.Succeeded = false;
这是HttpPost控制器
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(EditUserViewModel editUser,
params string[] selectedRole)
{
if (ModelState.IsValid)
{
var user = await UserManager.FindByIdAsync(editUser.Id);
if (user == null)
{
return HttpNotFound();
}
// if email is unchanged don't update it.
if (user.Email != editUser.Email)
{
user.Email = editUser.Email;
user.EmailConfirmed = false;
}
var userRoles = await UserManager.GetRolesAsync(user.Id);
selectedRole = selectedRole ?? new string[] { };
// Identity tries to update the email address here and returns an error?
var result = await UserManager.AddToRolesAsync(user.Id,
selectedRole.Except(userRoles).ToArray<string>());
if (!result.Succeeded)
{
ModelState.AddModelError("", result.Errors.First());
return View(new EditUserViewModel()
{
Id = user.Id,
MemberName = user.Name,
Email = user.Email,
MemberAddress = user.Address,
RolesList = RoleManager.Roles.ToList().Select(x => new SelectListItem()
{
Selected = userRoles.Contains(x.Name),
Text = x.Name,
Value = x.Name
})
});
}
result = await UserManager.RemoveFromRolesAsync(user.Id, userRoles.Except(selectedRole).ToArray<string>());
if (!result.Succeeded)
{
ModelState.AddModelError("", result.Errors.First());
return View();
}
return RedirectToAction("Index");
}
ModelState.AddModelError("", "Something failed.");
return View(editUser);
}
这是UserManager类(样本中的Vanilla):
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
我可以看到ApplicationUserManager Create
中的IdentityConfig
方法正在触发,这就是'RequireUniqueEmail = true;'设置,但我不明白为什么它试图创建一个新用户,而不仅仅是验证UserManager.FindByIdAsync(editUser.Id)
返回上面的现有用户。这是ApplicationUserManager
类:
public class ApplicationUserManager : UserManager<ApplicationUser>
{
public ApplicationUserManager(IUserStore<ApplicationUser> store)
: base(store)
{
}
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options,
IOwinContext context)
{
var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationIdentityDbContext>()));
// Configure validation logic for usernames
manager.UserValidator = new UserValidator<ApplicationUser>(manager)
{
AllowOnlyAlphanumericUserNames = false,
// why is this being enforced on an existing user when the email
// address is not being updated but UserRoles are?
RequireUniqueEmail = true
};
// Configure validation logic for passwords
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = true,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};
// Configure user lockout defaults
manager.UserLockoutEnabledByDefault = true;
manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
manager.MaxFailedAccessAttemptsBeforeLockout = 5;
// Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user
// You can write your own provider and plug in here.
manager.RegisterTwoFactorProvider("PhoneCode", new PhoneNumberTokenProvider<ApplicationUser>
{
MessageFormat = "Your security code is: {0}"
});
manager.RegisterTwoFactorProvider("EmailCode", new EmailTokenProvider<ApplicationUser>
{
Subject = "SecurityCode",
BodyFormat = "Your security code is {0}"
});
manager.EmailService = new EmailService();
manager.SmsService = new SmsService();
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
manager.UserTokenProvider =
new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
}
return manager;
}
}
正如您所看到的,我没有配置双因素身份验证。您可以提供的任何见解将是最有帮助的。在此先感谢。