Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

This is a followup question for this one: How does DataAnnotations really work in MVC? There is an example custom validation, and a "Self Validate Model" was mentioned. It is quite interesting, but I don't understand how to write a client side validation for it.

Can my model object implement the IClientValidateble interface (or it is for the dataannotation attributes only?), I would like to see an example on how to do it.

Edit: To my understanding, the "Self Validate Model" works without using DataAnnotations, and declares the validation logic inside the class which properties I'm validating, and it's not (necessarily) using attributes to validate something.

All of the examples I have seen on custom client side validation is about the dataannotation attribute implementing IClientValidatable.

When I'm declaring my validation logic in my class, I don't use attributes to validate the models state.

How to write clientside validation when I'm declaring my validation logic in the Validate method of the model class implementing the IValidatebleObject interface?

Can the class I'm actually passing to the view implement the IClientValidatable interface or something similar?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
476 views
Welcome To Ask or Share your Answers For Others

1 Answer

Taking the same answer:

After you implement the Self Validate Model, witch is a Server Side Validation, you need to create the Client Side Validation part, for that, just create this 3 steps:

  • Implement
  • Implement a jQuery validation method
  • Implement an unobtrusive adapter

append to your IClientValidateble class

public IEnumerable<ModelClientValidation> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
    var rule = new ModelCLientValidationRule();
    rule.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName());
    rule.ValidationType = "greater"; // This is what the jQuery.Validation expects
    rule.ValidationParameters.Add("other", OtherPropertyName); // This is the 2nd parameter

    yield return rule;
}

Then you need to write the new jQuery Validator and the metadata adapter that will link the jQuery.Validation with your code providing the correct data- attributes for that field (if of course, UnobtrusiveJavaScriptEnabled is true)

create a new js file and attach to your <head> for example as

<script src="@Url.Content("~/Scripts/customValidation.js")" type="text/javascript"></script>

and append the new validation

jQuery.validator.addMethod("greater", function(value, element, param) {
    // we need to take value and compare with the value in 2nd parameter that is hold in param
    return Date.parse(value) > Date.parse($(param).val());
});

and then we write the adapter

jQuery.validator.unobtrusive.adapters.add("greater", ["other"], function(options) {
    // pass the 'other' property value to the jQuery Validator
    options.rules["greater"] = "#" + options.param.other;
    // when this rule fails, show message that comes from ErrorMessage
    options.messages["greater"] = options.message;
});

You can view this in the AccountModel.cs when you create a new MVC3 Web Applicatoin, it shows this method that implements the IClientValidatable

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public sealed class ValidatePasswordLengthAttribute : ValidationAttribute, IClientValidatable
{
    private const string _defaultErrorMessage = "'{0}' must be at least {1} characters long.";
    private readonly int _minCharacters = Membership.Provider.MinRequiredPasswordLength;

    public ValidatePasswordLengthAttribute()
        : base(_defaultErrorMessage)
    {
    }

    public override string FormatErrorMessage(string name)
    {
        return String.Format(CultureInfo.CurrentCulture, ErrorMessageString,
            name, _minCharacters);
    }

    public override bool IsValid(object value)
    {
        string valueAsString = value as string;
        return (valueAsString != null && valueAsString.Length >= _minCharacters);
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        return new[]{
            new ModelClientValidationStringLengthRule(FormatErrorMessage(metadata.GetDisplayName()), _minCharacters, int.MaxValue)
        };
    }
}
#endregion

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...