Search code examples
c#asp.netasp.net-mvcasp.net-mvc-4modelstate

ModelState.IsValid is false when modifying model before checking validity


The issue I am experiencing is I am modifying my model in the post action, instead of having it filled in through the form (the fields are a password hash and password salt) for obvious reasons. When post to the action, obviously the password hash and salt are computed values not user entered. The issue is, if I generate them and assign the values to my posted customer model, model state still says they are required even though the properties have values. See code below. This is my register action.

[HttpGet]
    public ActionResult Register()
    {
        return View();
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Register(Customer customer)
    {

        var password = Request.Form.Get("password");
        var ConfirmPassword = Request.Form.Get("confirmpassword");

        if ((password != null && ConfirmPassword != null) && (!string.IsNullOrWhiteSpace(password)
            && !string.IsNullOrWhiteSpace(ConfirmPassword)) && password == ConfirmPassword)
        {
            //generate a password salt
            var passwordsalt = Models.Helpers.PasswordHasher.GetSalt();
            //convert it into a string that can be used again by calling the Convert.FromBase64String(string); function on what will be stored
            customer.PasswordSalt = Convert.ToBase64String(passwordsalt);
            //compute the password hash here and store it in the customer
            customer.PasswordHash = Models.Helpers.PasswordHasher.ComputeHash(password, "SHA256", passwordsalt);

        }
        else if (!Models.Helpers.ValidationLibrary.ValidatePasswordRequirements(password))
        {
            ModelState.AddModelError("", "Password must be 8 characters long, have at least one number or symbol");
        }
        else
        {
            ModelState.AddModelError("", "Password and confirm password do not match");
        }


            if (ModelState.IsValid)
        {
            //db.Customers.Add(customer);
            //db.SaveChanges();

            UserRegistration regularUser = new UserRegistration();

            regularUser.customer = customer;
            regularUser.role = new XREF_CustomerRole { Role_ID = 3, Customer_ID = customer.Customer_ID };

            Models.Helpers.Helper.createUser(regularUser);

            return Login(new UserLogin { Email = customer.Email, Password = customer.PasswordHash, RememberMe = false });
        }
        return View(customer); ;
    }

Here is a screenshot of the values.Screenshot of customer model

And here is a screenshot of the values in model state Values in model state Along with their corresponding keys Key in model state


Solution

  • That's normal and it is how HTML helpers work. They first use the value of the POST request and after that the value in the model. This means that even if you modify the value of the model in your controller action if there is the same variable in the POST request your modification will be ignored and the POSTed value will be used.

    ASP.Net MVC Html.HiddenFor with wrong value