2013-01-23 41 views
0

我在執行數據類型驗證時遇到問題依賴於另一個字段。我在這裏找到的大多數例子都是基於另一個字段的值來創建一個字段(MaidenName僅在IsMarriedtrue時才需要)。如何在依賴其他字段的字段上進行數據類型驗證?

我的模型

public class AttributeValuesModel 
{ 
    public IList<AttributeModel> Values {get; set;} 
} 

public class AttributeModel 
{ 
    [Required] 
    public string AttributeName {get; set;} 

    [Required] 
    public string AttributeValue {get; set;} 

    [Required] 
    public int DataTypeId {get; set;} 
} 

我想這樣做是爲了驗證基於DataTypeId的值的AttributeValue用戶輸入。爲了清楚起見,我甚至在向用戶展示視圖之前知道DataTypeId的值。

//Possible values for DataTypeId are 
    //1 for decimal 
    //2 for dates 
    //3 for integer 

這可能嗎?

回答

0

推出自己的驗證屬性並不難。我前一段時間已經實施了。它檢查其他屬性的值是否小於以此屬性裝飾的屬性:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited=true)] 
public class SmallerThanAttribute : ValidationAttribute 
{ 
    public SmallerThanAttribute(string otherPropertyName) 
    { 
     this.OtherPropertyName = otherPropertyName; 
    } 

    public string OtherPropertyName { get; set; } 
    public string OtherPropertyDisplayName { get; set; } 

    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     return IsValid(OtherPropertyName, value, validationContext); 
    } 

    private ValidationResult IsValid(string otherProperty, object value, ValidationContext validationContext) 
    { 
     PropertyInfo otherPropertyInfo = validationContext.ObjectType.GetProperty(otherProperty); 

     if (otherPropertyInfo == null) 
     { 
      throw new Exception("Could not find property: " + otherProperty); 
     } 

     var displayAttribute = otherPropertyInfo.GetCustomAttributes(typeof(DisplayAttribute), true).FirstOrDefault() as DisplayAttribute; 

     if (displayAttribute != null && OtherPropertyDisplayName == null) 
     { 
      OtherPropertyDisplayName = displayAttribute.GetName(); 
     } 

     object otherPropertyValue = otherPropertyInfo.GetValue(validationContext.ObjectInstance, null); 

     var smaller = (IComparable) value; 
     var bigger = (IComparable) otherPropertyValue; 

     if (smaller == null || bigger == null) 
     { 
      return null; 
     } 

     if (smaller.CompareTo(bigger) > 0) 
     { 
      return new ValidationResult(string.Format(ValidatorResource.SmallerThan, validationContext.DisplayName, OtherPropertyDisplayName)); 
     } 

     return null; 
    } 
} 

有一個問題。錯誤消息格式是在資源類屬性(ValidatorResource.SmallerThan)中定義的,所以它不是可插入的 - 我不需要這個。不過,我認爲它對你來說仍然是一個很好的起點。

1

您可以查看FoolProof驗證擴展ASP.NET MVC。它們包含可用於執行條件驗證的驗證屬性,如[RequiredIf]

而一個更強大的驗證庫(以及我使用和推薦的)是FluentMVC。與驗證數據註釋相反,此庫允許您執行命令式驗證而不是聲明式驗證。這使您可以表達任意複雜的規則和相關屬性之間的規則。

+0

我在發佈我的問題之前看過FoolProof,但我認爲他們不會進行數據類型驗證。他們最近的是'[RequiredIfRegExMatch]'和'[RequiredIfNotRegExMatch]',我覺得它有點推動它達到數據類型驗證的極限。我將檢查FluentMVC,因爲它在模板模板部分(頁面底部)中提到了'DataType'。 –

+0

那麼用FluentMVC你可以獲得所有的歡樂(和力量)。 –

+0

既然你說過你已經使用了'FluentMVC',我想知道你是否已經在類似的情況下使用了內建的'DataType'模板了嗎?這意味着數據類型驗證僅在滿足對其他字段的依賴關係時觸發。 –