如何在ASP.NET MVC 2 RC中编写自定义客户端jQuery验证?

时间:2010-01-11 16:17:16

标签: asp.net-mvc asp.net-mvc-2 validation

我在ASP.NET MVC 2中阅读了Phil Haack's post关于自定义客户端验证的问题。我想做同样的事情,但使用jQuery适配器并使用ASP.NET MVC 2 RC(而不是MVC)帖子使用的2 Beta)。有没有人能够想出如何做到这一点?

我特别想要实现密码匹配验证(即密码和确认密码必须匹配)。 ASP.NET MVC 2 RC VS.NET项目模板确实展示了如何在服务器端(使用PropertiesMustMatchAttribute)实现它,而不是在客户端实现。

3 个答案:

答案 0 :(得分:15)

我假设您已经按照Phil Haack的说明({3}})了解了如何使用MS AJAX客户端验证进行自定义验证。要使它与jQuery一起使用,您需要修改MicrosoftMvcJQueryValidation.js文件:

  • 在__MVC_CreateRulesForField(validationField)函数中,您需要添加一个case语句。继续菲尔的例子,你需要添加:

    案例“价格”:

    __ MVC_ApplyValidator_Price(rulesObj,thisRule.ValidationParameters [“min”]);

    断;

  • 然后您需要创建__MVC_ApplyValidator_Price函数:

function __MVC_ApplyValidator_Price(object,value){

// min is what jQuery Validate uses to validate for minimum values
object["min"] = value;

}

这应该足以让菲尔的榜样有效。

现在,关于您的PropertiesMustMatchAttribute验证,它看起来不像MVC为装饰类的属性生成客户端json验证定义。由于必须在模型上使用PropertiesMustMatchAttribute(而不是属性),我无法弄清楚如何使其触发客户端验证。相反,我采取了不同的方法。我创建了一个虚拟验证属性,其IsValid()重载始终返回true,并在属性上使用此属性。这只是一个伪属性,它将验证逻辑委托给jQuery验证器的equalTo函数。这是虚拟属性:

public class PropertiesMustMatchClientTriggerAttribute : ValidationAttribute
{
    public string MatchProperty { get; set; }

    public PropertiesMustMatchClientTriggerAttribute(string matchProperty)
    {
        MatchProperty = matchProperty;
        ErrorMessage = "{0} doesn't match {1}.";
    }
    public override bool IsValid(object value)
    {
        return true;
    }

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

以下是自定义验证器:

public class PropertiesMustMatchClientTriggerValidator : DataAnnotationsModelValidator<PropertiesMustMatchClientTriggerAttribute>
{
    private string _message;
    private string _matchProperty;

    public PropertiesMustMatchClientTriggerValidator(ModelMetadata metaData, ControllerContext context, PropertiesMustMatchClientTriggerAttribute attribute)
        : base(metaData, context, attribute)
    {
        _message = attribute.FormatErrorMessage(metaData.DisplayName);
        _matchProperty = attribute.MatchProperty;
    }

    public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
    {
        var rule = new ModelClientValidationRule
        {
            ErrorMessage = _message,
            ValidationType = "equalTo"
        };
        rule.ValidationParameters.Add("matchField", _matchProperty);

        return new[] { rule };
    }
}

上述自定义验证程序需要在Phil的博客中在Application_Start()中注册:

DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(PropertiesMustMatchClientTriggerAttribute),typeof(PropertiesMustMatchClientTriggerValidator));

最后,您需要修改MicrosoftMvcJQueryValidation.js文件:

  • 将以下case语句添加到__MVC_CreateRulesForField:

case“equalTo”:

__ MVC_ApplyValidator_EqualTo(rulesObj,thisRule.ValidationParameters [“matchField”]);

中断;

  • 添加此功能:

function __MVC_ApplyValidator_EqualTo(object,elemId){

object["equalTo"] = document.getElementById(elemId);

}

现在您需要将虚拟验证属性附加到属性:

    [PropertiesMustMatchClientTrigger("Password")]
    public string ConfirmPassword { get; set; }

应该这样做。

创建这个虚拟属性有点难看,所以我希望有人能想出更优雅的解决方案。

答案 1 :(得分:1)

以下是添加自定义jQuery验证的方法:

$.validator.addMethod("noSpaces", function(value, element) {
    if ($(element).val().indexOf(" ") >= 0) {
        return false;
    } else {
        return true;
    }
}, "Value must not contain spaces");

答案 2 :(得分:0)

我知道这是一个旧帖子,你正在/正在使用MVC2,但MVC3现在附带了CompareAttribute,它可以用于密码确认匹配的用例。

来源:http://www.nickriggs.com/posts/asp-net-mvc-3-data-annotations-provide-property-level-contingent-validation/