2016-09-21 16 views
2

背景定製DataAnnotation IsValid的不調用

您好所有,

基本上,我寫在.NET核心類庫自定義數據註解,將驗證一個IEnumerable至少有一定數量的元素。


的問題

出於某種原因,運行有效性的時候,和isValid永遠不會被調用。我已經發現了一些關於這個問題的其他SO問題,但他們都有一個與我不同的問題(基本上,他們並沒有實際驗證他們的對象)。但是,我正在驗證我的對象(稱爲Validator.TryValidateObject(...)),但是,IsValid從未被調用過。

如果我使用任何現成的驗證屬性(例如「必需」),它將按預期運行。


守則

MinElementsAttribute.cs

public class MinElementsAttribute : ValidationAttribute 
{ 
    readonly int minElements; 

    public MinElementsAttribute(int minElements) : base($"Collection must have a size of at least {minElements}") 
    { 
     this.minElements = minElements; 
    } 

    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     var list = value as IEnumerable<object>; 

     if(list == null || list.Count() < this.minElements) 
     { 
      return new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName)); 
     } 

     return ValidationResult.Success; 
    } 
} 

MinElementsTests.cs

[Fact] 
public void TestValidation() 
{ 
    var validationResults = new List<ValidationResult>(); 
    var testObject = new TestObject(); 

    // Should be false since I have not added anything to the list 
    var isValid = Validator.TryValidateObject(testObject, new ValidationContext(testObject), validationResults); 

    // Fails since isValid comes back as true because IsValid on MinElementsAttribute is never called 
    Assert.False(isValid); 
    Assert.NotEmpty(validationResults); 
} 

internal class TestObject 
{ 
    public TestObject() 
    { 
     this.StringList = new List<string>(); 
    } 

    [MinElements(3)] 
    public List<string> StringList { get; set; } 
} 

編輯:解決方案

請參閱解決方案的接受答案。我想補充一點,還要注意通過將繼承從RequiredAttribute而不是ValidationAttribute更改爲可以隱式地強制執行所有對象屬性的驗證。

+1

請添加的TestObject類? –

+0

它就在我的最新編輯:) –

回答

6

Validator.TryValidateObject類有一些重載方法。你想用這一個:

public static bool TryValidateObject(object instance, ValidationContext validationContext, ICollection<ValidationResult> validationResults, bool validateAllProperties); 

MSDN article

validateAllProperties
類型:System.Boolean
真正驗證所有屬性; 如果爲false,則僅驗證所需的屬性。

您必須使用此方法,因爲您的屬性不是從RequiredAttribute類派生的。

我的樣本

var validationResults = new List<ValidationResult>();    
var testObject = new TestObject(); 
ValidationContext contexts = new ValidationContext(testObject, null, null);    
var isValid = Validator.TryValidateObject(testObject, contexts, validationResults, true); 
+0

好的答案!我做了一個編輯來清理語法,格式化,並將URL改爲指向英文版本的文檔。 –

+0

謝謝你:) –

+0

這太棒了!我不知道從RequiredAttribute派生來隱式執行對象上所有屬性的驗證(這是我想要的)。 –

相關問題