Asp.Net Identity 2.0 AddToRolesAsync - 错误"电子邮件somename@somedomain.com已被采取"

时间:2014-07-28 19:15:33

标签: c# asp.net asp.net-mvc asp.net-identity-2

我在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;
    }
}

正如您所看到的,我没有配置双因素身份验证。您可以提供的任何见解将是最有帮助的。在此先感谢。

0 个答案:

没有答案