2011-08-25 52 views
0

力验证我已经使用了自定义的验证下列类:MVC3自定义不引人注目的验证 - 从复选框

[AttributeUsage(AttributeTargets.Property, AllowMultiple=false, Inherited=true)] 
public sealed class RequiredIfAnyTrueAttribute : ValidationAttribute, IClientValidatable 
{ 
    private const string DefaultErrorMessage = "{0} is required"; 

    public List<string> OtherProperties { get; private set; } 

    public RequiredIfAnyTrueAttribute(string otherProperties) 
     : base(DefaultErrorMessage) 
    { 
     if (string.IsNullOrEmpty(otherProperties)) 
      throw new ArgumentNullException("otherProperty"); 

     OtherProperties = new List<string>(otherProperties.Split(new char[] { '|', ',' })); 
    } 

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

    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     if (value == null) 
     { 
      foreach (string s in OtherProperties) 
      { 
       var otherProperty = validationContext.ObjectType.GetProperty(s); 
       var otherPropertyValue = otherProperty.GetValue(validationContext.ObjectInstance, null); 

       if (otherPropertyValue.Equals(true)) 
        return new ValidationResult(FormatErrorMessage(validationContext.DisplayName)); 
      } 
     } 

     return ValidationResult.Success; 
    } 

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
    { 
     var clientValidationRule = new ModelClientValidationRule() 
     { 
      ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()), 
      ValidationType = "requiredifanytrue" 
     }; 

     clientValidationRule.ValidationParameters.Add("otherproperties", string.Join("|",OtherProperties)); 

     return new[] { clientValidationRule }; 
    } 
} 

我的视图模型为:

public class SampleViewModel 
{ 
    public bool PropABC { get; set; } 
    public bool PropXYZ { get; set; } 

    [RequiredIfAnyTrue("PropABC|PropXYZ")] 
    public int? TestField { get; set; } 
} 

当我的强类型的视图渲染,一切都看向工作正常。如果选择了PropABC或PropXYZ,那么我需要为TestField输入一个值。客户端和服务器端验证都是有效的。

然而,鉴于事件的顺序如下:

  1. 检查PropABC
  2. 提交表单
  3. 客户端验证火灾的TestField需要
  4. 取消选中PropABC
  5. 客户端验证不重-firefire和验证消息 将一直保留,直到表单提交

为了解决#5,我通常会通过jquery onready将点击事件附加到复选框以重新验证。

是否有一个首选/推荐的方式来手动强制客户端验证给予MVC3 + unobstrusive + jQuery的?

+0

你可以发布自定义客户端验证,以及? –

回答

1

肖恩,附加事件是获得验证的最好方法。

我建议创建一个名为“验证”(或沿着这些线)的类,将其添加到每个要验证的元素,然后使用jQuery附加到点击和模糊事件(以及可能的更改事件)与类中的每个元素,并验证元素,像这样:

$("form").validate().element(this); 
1

您是否需要编写自己的属性?如果不是,我认为你可能能够避免“重塑车轮”

FoolProof伟大的作品。你得到它作为一个NuGet包。

NuGet: install-package foolproof 

它包括很多关于上即时必需字段和这样的各种组合马丽娟属性。

+0

我尝试了FoolProof,但无法让它与我的方案一起工作。如果其他几个字段都为真,我需要给定字段。 FoolProof没有提供内置的,我无法弄清楚如何成功扩展它。 [我的帖子到万无一失的讨论](http://foolproof.codeplex.com/discussions/270093) – Shawn

+0

IMO:我会努力[学习如何]让万无一失工作,即使这需要扩展它。你将花费在前面的时间远不及你从头开始编写你自己的解决方案的时间。 –

+0

如果我忽略我的要求来验证多个目标,并针对单个目标属性开箱即用地使用FoolProof的RequireIfTrue属性,则存在上述同样的问题。当复选框未被选中时,验证不会触发,而只会在再次单击提交时触发。 **是否存在更好的方法来重新验证复选框交互,而不是通过jquery onready连接onclick事件?** – Shawn

0

万无一失仍处于测试阶段,不与嵌套视图模型的工作,还与阵列