【问题标题】:MVC 4 Custom data annotation manual jquery validation callMVC 4自定义数据注释手动jquery验证调用
【发布时间】:2012-08-13 09:58:16
【问题描述】:

我们正在尝试使用 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() 似乎没有做任何事情似乎触发表单验证的唯一调用是 $('form').valid() 但这似乎只显示了内置验证,例如 [Required] 属性,并且显示自定义验证消息的唯一方法是使用提交按钮回发表单。

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

【问题讨论】:

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


    【解决方案1】:

    好的,所以我找到了一种方法来获得我想要的结果,尽管它比我想要/想象的要多一点工作。 我缺少的东西是我没有在我的自定义验证类中实现 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()

    希望这对某人有帮助:)

    【讨论】:

    • 有没有办法将匿名 JS 方法(传递给 jQuery.validator.addMethod() 的方法)的值发送回 C#,以便在错误消息中显示?就我而言,我不需要服务器端验证,只需要客户端。我知道这是一个糟糕的设计决定,但那是另一回事了。
    【解决方案2】:
    【解决方案3】:

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

    【讨论】:

    • err 是的,您可以使用更通用的脚本,但在这种情况下,我每页只有 1 个电话 1 个移动元素,所以它有点通用,但您可以更改类的 ID if ($('.Option1').val() == '' && $('.Option2').val() == '') 这将比电话类型更通用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-13
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多