3

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?

4

1 回答 1

2

采取相同的答案:

实现自我验证模型后,女巫是服务器端验证,您需要创建客户端验证部分,为此,只需创建以下 3 个步骤:

  • 实施
  • 实现一个 jQuery 验证方法
  • 实现一个不显眼的适配器

附加到你的IClientValidateble班级

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;
}

然后,您需要编写新的jQuery Validator元数据适配器,将 jQuery.Validation 与您的代码链接起来,data-为该字段提供正确的属性(如果当然UnobtrusiveJavaScriptEnabled是真的)

创建一个新js文件并附加到您<head>的例如

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

并附加新的验证

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());
});

然后我们编写适配器

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;
});

您可以在AccountModel.cs创建新的 MVC3 Web 应用程序时查看此内容,它显示了实现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
于 2011-03-01T14:36:36.620 回答