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

Buu*_*yen 12 validation asp.net-mvc asp.net-mvc-2

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

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

Joh*_*ika 15

我假设您已经按照Phil Haack的说明http://haacked.com/archive/2009/11/19/aspnetmvc2-custom-validation.aspx)了解如何使用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;
Run Code Online (Sandbox Code Playgroud)

}

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

现在,关于您的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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是自定义验证器:

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 };
    }
}
Run Code Online (Sandbox Code Playgroud)

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

DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof运算(PropertiesMustMatchClientTriggerAttribute)的typeof(PropertiesMustMatchClientTriggerValidator));

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

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

案例"equalTo":

__MVC_ApplyValidator_EqualTo(rulesObj,thisRule.ValidationParameters ["matchField"]);

打破;

  • 添加此功能:

function __MVC_ApplyValidator_EqualTo(object,elemId){

object["equalTo"] = document.getElementById(elemId);
Run Code Online (Sandbox Code Playgroud)

}

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

    [PropertiesMustMatchClientTrigger("Password")]
    public string ConfirmPassword { get; set; }
Run Code Online (Sandbox Code Playgroud)

应该这样做.

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