身份2.1 - 使用临时密码的用户创建导致ModelState无效

时间:2015-05-27 15:25:35

标签: asp.net-mvc asp.net-identity

我尝试使用临时密码注册用户,该用户在注册过程中立即通过电子邮件重置密码。在测试代​​码时,我在!ModelState.Valid检查下得到错误"密码字段是必需的"。我在model.Password下定义了一个临时使用的密码,所以我在这里缺少什么?

// POST: /Account/Register
    [HttpPost]
    [Authorize(Roles = "SuperAdmin, LEAAdmin, SchoolAdmin")]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Register(RegisterViewModel model)
    {
        model.BackgroundOnFile = false;

            var userDetails = new ApplicationUser { 
                Id = model.Id, 
                UserName = model.Email, 
                Title = model.Title, 
                Email = model.Email, 
                FirstName = model.FirstName, 
                LastName = model.LastName, 
                LEAID = model.LEAID, 
                SchoolID = model.SchoolID, 
                BackgroundOnFile = model.BackgroundOnFile, 
                BoardStart = model.BoardStart, 
                BoardEnd = model.BoardEnd, 
                PhoneNumber = model.PhoneNumber, 
                IsBoardChair = model.IsBoardChair, 
                IsBoardMember = model.IsBoardMember, 
                IsAccountActive = model.IsAccountActive,
            };

//Declaring in Scope
                var result = new IdentityResult();
            //Process if new
            if(model.Id == "" || model.Id == "undefined" || model.Id == "null" || model.Id == "-9999")
            {
                model.Password = "D0neW!thTh15";
                if (ModelState.IsValid)
                {
                result = await UserManager.CreateAsync(userDetails, model.Password);

                var getPassword = new ForgotPasswordViewModel
                {
                    Email = model.Email
                };

                //Email PW
                await ForgotPassword(getPassword);
                }

                if(!ModelState.IsValid)
                {
                    string validationErrors = string.Join(",",ModelState.Values.Where(E => E.Errors.Count > 0).SelectMany(E => E.Errors).Select(E => E.ErrorMessage).ToArray());
                }

            }

            //Process if update
            if (model.Id != "" || model.Id != "undefined" || model.Id != "null" || model.Id != "-9999")
            {
                if (ModelState.IsValid)
                {
                result = await UserManager.UpdateAsync(userDetails);
                }
            }


            //Process Roles
            //Remove access if deactivated
            if (model.IsAccountActive == false)
            {
                var user = await UserManager.FindByIdAsync(userDetails.Id);
                await UserManager.RemoveFromRolesAsync(userDetails.Id, UserManager.GetRoles(userDetails.Id).ToArray());
                await UserManager.AddToRoleAsync(userDetails.Id, "Deactivated");
                userDetails.LockoutEnabled = true;
                await UserManager.UpdateAsync(userDetails);
            }

            else
            {

                //Moved to separate controller, for safety Admin rights can only be done for existing users

                if(model.LEAAdmin == true)
                {
                    await UserManager.AddToRoleAsync(userDetails.Id, "LEAAdmin");
                }

                //LEAAdmin is higher level, so don't allow override to a lower level
                if(model.IsBoardChair == true && model.LEAAdmin == false)
                {
                    await UserManager.AddToRoleAsync(userDetails.Id, "SchoolAdmin");
                }

                else
                {
                    await UserManager.AddToRoleAsync(userDetails.Id, "User");
                }

            }




            if (result.Succeeded)
            {
                //await SignInManager.SignInAsync(userDetails, isPersistent:false, rememberBrowser:false);

                // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771
                // Send an email with this link
                // string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
                // var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
                // await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>");

                //return RedirectToAction("Index", "Home");
                return Json("Password sent!");
            }
            AddErrors(result);


        // If we got this far, something failed, redisplay form
        //return View(model);
        return View();
    }

这是ApplicationUser的代码,以备不时之需:

 public class ApplicationUser : IdentityUser
{

    //Extra items required to register
    public string Title { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int LEAID { get; set; }
    public int SchoolID { get; set; }
    //public string Address1 { get; set; }
    //public string Address2 { get; set; }
    //public string City { get; set; }
    //public string State { get; set; }
    //Post Code is a string to accomodate future possible Canadian style post codes
    //public string PostCode { get; set; }
    public bool BackgroundOnFile { get; set; }
    public bool IsBoardMember { get; set; }
    public bool IsBoardChair { get; set; }
    public System.DateTime? BoardStart { get; set; }
    public System.DateTime? BoardEnd { get; set; }
    public string NominatedBy { get; set; }
    public bool IsAccountActive { get; set; }


    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        return userIdentity;
    }
}

更新: 注册请求的ViewModel

 [Required]
 [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm password")]
    [System.Web.Mvc.CompareAttribute("Password", ErrorMessage = "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }

1 个答案:

答案 0 :(得分:0)

当值传递到服务器并创建RegisterViewModel时,ModelState验证在默认的ModelBinder中进行。这意味着更新模型时ModelState.IsValid不会自动更改。要重新验证模型,您可以执行以下操作:

//Set password here
ModelState.Clear(); // Clear the current ModelState
TryValidateModel(model); // Try to re-validate.
if (ModelState.IsValid) // Now check!
{
    ...
}

通过执行此操作,您将清除当前的ModelState,然后强制重新生效。