MVC 4自定义数据注释手动jquery验证调用

时间:2012-08-13 09:58:17

标签: jquery asp.net-mvc c#-4.0 data-annotations

我们正在尝试使用MVC 4数据注释创建一些自定义验证,我们创建的验证是一种消息提示而不是限制性验证。 首先,我们创建了一些继承自ValidationAttribute的自定义验证类  类和重写IsValid()方法来测试数据并返回ValidationResult(如果无效)。 显示此数据的视图具有使用EditorTemplates显示剃刀生成的数据的部分视图,使用我们的自定义数据注释和许多内置验证,所有这些都包含在这样的表单中

@using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl }))

我们的要求是让用户回发数据并部分保存表单,但在任何无效字段上提示他们,所以使用 表单上的CSS类提交允许回传,如此

<input type="submit" value="Save" class="cancel"/>

所有这一切都运行正常但我们现在要求在页面加载时显示所有错误消息,在我尝试之前我没有看到它是一个问题......

我发现了一些在$(document).ready事件中使用jquery的例子,这些事件调用了表格有效的方法,如下所示

Manual form validation in MVC 3 and JQuery

但这对我们来说似乎不起作用$('form')。Validate()似乎没有做任何事情,似乎唯一的调用似乎触发了表单验证 $(“形式”)。有效的() 但这似乎只显示内置验证,如[Required]属性,并且获取自定义验证消息的唯一方法是使用提交按钮发回表单。

必须有一种方法可以让我的自定义数据注释显示消息,而无需在第一时间回复页面吗? 任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:6)

好的,所以我找到了一种方法来获得我想要的结果,虽然它比我想象的还要多一点。 我失踪的东西是我没有在我的自定义验证类中使用IClientValidatable,并且必须将我的自定义验证添加到我尝试过的jQuery Validator addmethod,但是在自定义验证类中没有使用IClientValidatable,我将很快通过假设你已经设置/包含了所有的jQuery内容,如何让这个工作正常工作

首先创建使用自定义验证属性的简单模型

public class Person
{
    [Required]
    [Display( Name="Name")]
    public string Name { get; set; }
    public int Age { get; set; }

    //Uses a custom data annotation that requires that at lease it self or the property name passed in the constructor are not empty
    [OneOfTwoRequired("Mobile")]
    public string Phone { get; set; }
    [OneOfTwoRequired("Phone")]
    public string Mobile { get; set; }
}

自定义验证类,它使用反射来获取传入的字符串名称的属性以使用

进行测试

注意截至2012年8月15日:如果您使用的是MVC 4,则需要使用引用的System.web.mvc 3.0来使用IClientValidatable,因为在MVC 4中似乎不存在ModelClientValidationRule

public class OneOfTwoRequired : ValidationAttribute, IClientValidatable
    {
        private const string defaultErrorMessage = "{0} or {1} is required.";

        private string otherProperty;

        public OneOfTwoRequired(string otherProperty)
            : base(defaultErrorMessage)
        {
            if (string.IsNullOrEmpty(otherProperty))
            {
                throw new ArgumentNullException("otherProperty");
            }

            this.otherProperty = otherProperty;
        }

        public override string FormatErrorMessage(string name)
        {
            return string.Format(ErrorMessageString, name, otherProperty);
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            PropertyInfo otherPropertyInfo = validationContext.ObjectInstance.GetType().GetProperty(otherProperty);

            if (otherPropertyInfo == null)
            {
                return new ValidationResult(string.Format("Property '{0}' is undefined.", otherProperty));
            }

            var otherPropertyValue = otherPropertyInfo.GetValue(validationContext.ObjectInstance, null);

            if (otherPropertyValue == null && value == null)
            {
                return new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName));
            }

            return ValidationResult.Success;
        }
        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            yield return new ModelClientValidationRule
            {
                ErrorMessage = FormatErrorMessage(metadata.DisplayName),
                //This is the name of the method aaded to the jQuery validator method (must be lower case)
                ValidationType = "oneoftworequired"
            };

        }
    }

将此添加到View或partialview,您必须确保它不在$(document).ready方法

    jQuery.validator.addMethod("oneoftworequired", function (value, element, param) {
        if ($('#Phone).val() == '' && $('#Mobile).val() == '')
            return false;
        else
            return true;
    });

    jQuery.validator.unobtrusive.adapters.addBool("oneoftworequired");

如果你想在没有回发或初始页面加载的情况下验证表单,似乎只需要jQuery验证器的东西,你只需要调用$('form')。valid()

希望这有助于某人:)

答案 1 :(得分:0)

答案 2 :(得分:0)

为什么您的C#代码是通用的,适用于任何两个字段,而脚本代码专门绑定到id为“#Phone”和“#Mobile”的字段?是否也没有办法概括脚本?