GillesDV
GillesDV

Reputation: 293

advice on making a custom validator in mvc

I'm currently making a C# application with MVC. There's a pretty ordinary registration form, where a user has to fill in a username and password, among other things. I'd like to implement a client side validation that checks whether or not the given password is strong enough or not. I already have a check in the setter of the Model, but it only checks when the submit button is pressed and thus the information is lost.

This is a simplified version of my check method:

    public static bool isThisPasswordValid(string pw)
    {
        int score = 0;
        //PW length is 8+
        if (pw.Length < 8)
            return false;
        else
            return true;
        //there's also a check of whether or not there's a lowercase, upper case letter, 
        //a number and a special character. Left that bit out 
    }

I already got the basics of a class, which I think I need, though I can't figure out how to finish and implement it. Any help would be much appreciated!

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited=false)]
public class MyPasswordValidator : ValidationAttribute, IClientValidatable
{
    private string currentPassword;

    protected override ValidationResult IsValid (object value, ValidationContext validationContext)
    {


        if (isThisPasswordValid(value.ToString()))
        {
            return ValidationResult.Success;
        }
        else{
            return new ValidationResult("Please enter a valid password");
        }

    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        return new[] { new ModelClientValidationSelectOneRule
        (FormatErrorMessage(metadata.DisplayName), currentPassword.Split(new char[] { ',' })) };
    }

Upvotes: 0

Views: 64

Answers (1)

Ric .Net
Ric .Net

Reputation: 5540

Are you aware of the RemoteAttribute?

This attribute takes an 'ActionMethod' and 'Controller' name as a string parameter. By returning a Json result this will be automatically called if you use the jquery.validation package/script.

The attribute could be used like:

[Remote("ValidatePassword", "Account")]
public string NewPassword { get; set; }

and the ActionMethod in the AccountController could look like this:

[Authorize]
public async Task<JsonResult> ValidatePassword (string NewPassword)
{
    var result = await this.DoSomeValidationOfPassword(NewPassword);

    if (result)
    {
        return this.Json(true, JsonRequestBehavior.AllowGet);
    }
    else
    {
        return this.Json("The password has the following demands:\r\n" 
                    + string.Join("\r\n", result.Errors), JsonRequestBehavior.AllowGet);
    }
}

In your view you can use a normal ValidationMessageFor html attribute like this:

@Html.PasswordFor(m => m.NewPassword, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.NewPassword, "", new { @class = "text-danger" })

Be sure to include the jquery.validate.js script!

Upvotes: 1

Related Questions