Question

I am working on a log on page, and no matter what I do I cannot get my ModelState.IsValid to return true so that I can sign the user in. I have this code in my controller:

[AllowAnonymous]
[HttpPost]
public ActionResult ValidateLogon(LogonModel logon)
{
    if (ModelState.IsValid)
    {
        StaffModel staff;
        if (staffAuthenticationService.ValidateLogon(logon.UserName, logon.Password, out staff, out logon))
        {
            staffAuthenticationService.SignIn(staff);
            return Json(new { success = true, redirect = "/Home/ModuleIndex", staff = staff });
        }
        ModelState.AddModelError("", "Username and/or Password may be incorrect");
    }

    return Json(new { errors = GetErrorsFromModelState() });   
}

My Logon Model has a Staff model and a User model, my service method validateLogon is passed a logon model. I tried using:

var errors = ModelState.SelectMany(x => x.Value.Errors.Select(z => z.Exception));

and logging the errors, but I see no errors and valid is always false.

Is there a better way to validate a user than with this dictionary object, or a work around that I have not found. I have been looking for a couple of hours.

Update:

public class LogonModel
{
    [Display(Name = "User")]
    [DataType("UserModel")]
    public UserModel User { get; set; }

    [Display(Name = "Staff")]
    [DataType("StaffModel")]
    public StaffModel Staff { get; set; }

    [Required(ErrorMessage = "Please enter your password")]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [Required(ErrorMessage = "Please enter your username")]
    [Display(Name = "User name")]
    public string UserName { get; set; }

    [Display(Name = "Terms Of Use Signed")]
    public bool IsTermsOfUseSigned { get; set; }

    [Display(Name = "Privacy Agreement Signed")]
    public bool IsPrivacyAgreementSigned { get; set; }

    [Display(Name= "System Message")]
    public string SystemLoginMessage { get; set; }

    [Display(Name="Version")]
    public string DatabaseVersion { get; set; }

    [Display(Name="Copyright Date")]
    public string CopyrightDate { get; set; }

    [Display(Name="Web Server")]
    public string WebServer { get; set; }

    [Display(Name = "Last Name")]
    [DataType(DataType.Text)]
    [Required(ErrorMessage = "Required")]
    [StringLength(50, ErrorMessage = "Value cannot exceed 50 characters")]
    public string LastName { get; set; }

    [Display(Name = "Date of Birth")]
    [DataType(DataType.Text)]
    [Required(ErrorMessage = "Required")]
    [StringLength(50, ErrorMessage = "Value cannot exceed 50 characters")]
    public string DateOfBirth { get; set; }

    [Display(Name = "Last 4 digits of XXXX SSN")]
    [DataType(DataType.Text)]
    [Required(ErrorMessage = "Required")]
    [StringLength(50, ErrorMessage = "Value must be 4 numbers")]
    public string SsnSuffix { get; set; }

    public int LogonValidationStep { get; set; }
}

This is what I see in the debugger when I hover over the the if statement: IsValid = false then when I step into the function it falls right to the error message.

Was it helpful?

Solution

If your check:

if (ModelState.IsValid)

returns false, that most probably means that one of the required fields in your model, used in the view is populated with incorrect result. After you post your model the DateOfBirth field seemed the most suspicious so removing the Required attribute made us able to find out what cause the problem and to solve the problem temporary.

From now on you have two options - just leave it as it is (I do not recommend that) or make further investigation why you are not getting the expected data for that field. In other words, don't avoid the problems, but try to solve them and learn from them.

If my post helped you you may as well accept it as an answer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top