6

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

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

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

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

所有这些都工作正常,但我们现在要求在页面加载时显示所有错误消息,直到我尝试它才发现这是一个问题......</p>

我在 $(document).ready 事件中找到了一些使用 jquery 的示例,这些示例调用了表单有效方法,如此处所示

MVC 3 和 JQuery 中的手动表单验证

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

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

4

3 回答 3

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

        }
    }

将此添加到视图或部分视图中,您必须确保它不在 $(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()

希望这可以帮助某人:)

于 2012-08-15T14:21:47.400 回答
0

这篇文章帮助了我,它似乎被移动了,但它在 Nuget 包中可用......

http://www.eminencedigital.com/blog/index.php/2011/11/29/tracking-down-the-new-namespace-for-modelclientvalidationrule-in-asp-net-mvc-4-0-developer-预习/

于 2013-01-03T13:21:44.690 回答
0

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

于 2013-08-01T20:16:51.043 回答