2012-08-13 98 views
6

我们正在尝试使用MVC 4数据注释创建一些自定义验证,我们创建的验证是一种比限制性验证更多的消息提示。 首先,我们创建了一些从ValidationAttribute类继承的自定义验证类,并重写IsValid()方法来测试数据,并在无效时返回ValidationResult。 显示此数据视图有使用我们的自定义数据注释和使用EditorTemplates显示剃刀局部视图生成的数据很多内置的验证,这一切都被包裹在一个形式类似这样的MVC 4自定义数据注释手册jquery验证调用

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

我们的要求是让用户回发数据和部分保存形式,但促使他们对任何无效的字段,以便使用窗体上的 CSS类提交允许回传,像这样

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

所有这一切都工作正常,但现在我们有要求在页面上显示所有的错误信息负载,我没有看到,直到我试图这是一个问题......

我发现,在所谓的形式有效的方法,因为在这里看到

Manual form validation in MVC 3 and JQuery的$(文件)。就绪事件使用jQuery的几个例子('form')。Validate()似乎没有做任何事情,似乎只触发表单验证是 $('form')。valid () 但是,这似乎只显示内置的验证,如[必需的]属性,获取自定义验证消息的唯一方法是显示使用提交按钮回发表格。

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

回答

6

好吧,所以我找到了一种方法来获得我想要的结果,虽然它比我想要的要多一点工作/想象它会是。 我错过的东西是我没有在我的自定义验证类中植入IClientValidatable,并且不得不将我的自定义验证添加到我尝试过的jQuery验证程序addmethod中,但是没有在定制验证类中植入IClientValidatable,我将快速运行通过如何得到这个工作的IM假设你把所有的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; } 
} 

使用反射获取属性自定义验证类的字符串名称通过测试

注为15/08/2012:如果您正在使用MVC 4,你需要的引用System.web.mvc 3.0使用IClientValidatable作为ModelClientValidationRule确实没有好像在MVC 4

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

     } 
    } 
存在

将此添加到视图或部分视图中,您必须确保它不在$(文档)中。准备好方法

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的验证的东西似乎只需要,如果你想验证的形式,而不回发或初始页面加载要做到这一点,你只需要调用$( “形”)。有效的()

希望这有助于有人:)

0

为什么你的C#代码一般情况下,适用于任何两个领域,而脚本代码特别依赖于与“#Phone”和“#Mobile”的ID的领域?没有办法概括脚本吗?

+0

err是的,你可以使用更通用的脚本,但这是一种情况,我只有每个页面有1个电话1个移动元素,所以它是通用的,但你可以改变类的ID如果($('。 (')。')。val()==''&& $('。Option2')。val()==''),这将更通用,然后只是电话类型。 – Troublesum 2014-02-18 16:13:45