Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remote ViewModel validation of nested objects not working

I have a class user which looks like this:

public class User
{
    public int UserId { get; set; }

    [Required(ErrorMessage = "A username is required.")]
    [StringLength(20, ErrorMessage = "Your username must be 4-20 characters.", MinimumLength = 4)]
    [RegularExpression("^[a-zA-Z0-9]*$", ErrorMessage = "Your username can only consist of letters and numbers.")]
    [Remote("UsernameExists", "RemoteValidation", ErrorMessage = "Username is already taken")]
    public string Username { get; set; }

    [Required(ErrorMessage = "A password is required.")]
    [MinLength(4, ErrorMessage = "Your password must have at least 4 letters.")]
    public string Password { get; set; }

    [Required(ErrorMessage = "An email address is required.")]
    public string Email { get; set; }
}

For the Register functionality I have created a ViewModel that holds a User object and a string for the password confirmation:

public class RegistrationViewModel
{
    public User User { get; set; }

    [DisplayName("Password confirmation")]
    [Required, Compare("User.Password", ErrorMessage = "The password do not match")]
    public string PasswordConfirmation { get; set; }
}

The first problem I run into is that I can't seem to get the validation for Compare("User.Password") to work as it does not seem to find the property on the user. Is there any way to validate the PasswordConfirmation property against the User.Password property?

The second problem is the Remote validation of the Username field. I followed David Hayden's tutorial at http://davidhayden.com/blog/dave/archive/2011/01/04/ASPNETMVC3RemoteValidationTutorial.aspx but the parameter username in the UsernameExists method is always null. Am I missing something here?

Edit:

I'm sorry but I was actually not clear enough on the error I receive for the password comparison. It works fine when filling in the fields, if the passwords do not match I will receive an error. However, when submitting the form I get the following error in the validation summary: Could not find a property named UserToRegister.Password.

Edit 2:

I have figured out part of the problem thanks to Joe's post. The remote validator posts back URL/?UserToRegister.Username=temp which obviously does not match the username parameter of my controller action. In order to map my action parameter to UserToRegister.Username the following is required:

public ActionResult UsernameExists([Bind(Prefix = "UserToRegister.Username")]string username)

This now correctly passes the parameter to the method. However I still get the error when using the Compare attribute on the password field.

Thanks.

like image 917
b3n Avatar asked Feb 16 '11 23:02

b3n


1 Answers

The issue with the validation of the PasswordConfigurmation property against the User.Password property is caused by a bug in in the 'jquery.validate.unobtrusive.js' file.

Originally, the jquery 'equalTo' function is:

adapters.add("equalto", ["other"], function (options) {
var prefix = getModelPrefix(options.element.name),
other = options.params.other,
fullOtherName = appendModelPrefix(other, prefix),
element = $(options.form).find(":input[name=" + fullOtherName + "]")[0];

setValidationValues(options, "equalTo", element);
});

You just need to modify this line:

element = $(options.form).find(":input[name=" + fullOtherName + "]")[0];

to:

element = $(options.form).find(":input[name='" + fullOtherName + "']")[0];

Note the addition on the single quotes around the 'fullOtherName' selector. Once you've made this change, the client side validation works as expected.

like image 126
Alexander van Trijffel Avatar answered Oct 14 '22 18:10

Alexander van Trijffel