2011-08-25 77 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

萬無一失仍處於測試階段,不與嵌套視圖模型的工作,還與陣列

相關問題