2013-07-31 85 views
1

我有以下代碼來測試一類屬性:RegularExpressionAttribute總是失敗

public class RegExtTest 
{ 
    [RegularExpression(@"^[A-z0-9]{6}$", ErrorMessage = "Lot must be 6 characters alphanumeric")] 
    public string Lot { get; set; } 
} 

和通用延伸方法來驗證包含這些對象

public static IEnumerable<string> ValidateObject(this object objectToValidate) 
    { 
     var result = new List<string>(); 
     var objType = objectToValidate.GetType(); 
     var properties = objType.GetProperties(); 
     foreach (var propertyInfo in properties) 
     { 
      var attrs = propertyInfo.GetCustomAttributes(typeof(ValidationAttribute), true); 
      foreach (var attribue in attrs) 
      { 
       try 
       { 
        var validationAttr = attribue as ValidationAttribute; 
        if (validationAttr != null) 
        { 
         validationAttr.Validate(objectToValidate,propertyInfo.Name); 
        } 
       } 
       catch (Exception e) 
       { 
        if (e is ValidationException) 
         result.Add(e.Message); 
       } 
      } 
     } 

     return result; 
    } 

然而驗證失敗時的一個或多個類值是「a23456」。我使用正則表達式對此進行了如下測試:

var isMatch = Regex.IsMatch(lbp.Lot, "^[A-z0-9]{6}$"); 

上述測試通過。 我在這裏做錯了什麼?在RegularExpressionAttribute中是否有一些問題我不知道

+0

是否確定[A-Z]是否有效?你不想使用[A-Za-z0-9]嗎? –

+0

當'a23456'通過時,你的意思是「驗證失敗」?這是一個6個字符的字母數字字符串,所以它應該通過,不是嗎? –

回答

2

您正在使用Validate方法錯誤。

而不是

validationAttr.Validate(objectToValidate,propertyInfo.Name); 

使用

validationAttr.Validate(propertyInfo.GetValue(objectToValidate, null),propertyInfo.Name); 

你必須通過實際價值的財產,以該Validate方法,因爲RegularExpressionAttribute類將只需要調用.ToString()value說法並根據其模式進行檢查。

但它仍然是最容易使用的Validator classas Jay already said in his answer.

+0

tx。那是現貨。我使用v3.5,所以不能使用驗證器。 – ASR

+0

我建議的另一件事是在'try ... catch'中顯式捕獲'ValidationException'。因爲它是其他任何被拋出的錯誤將被吞噬! – Jay

+0

我明白,但我不會把所有其他錯誤放在日誌中。這只是一個原型。最終版本會記錄所有其他例外 – ASR

2

您可以使用Validator簡化您的實現。有關更多詳細信息,請參閱here

這應該可以做到。

public static IEnumerable<string> ValidateObject(this object model) 
{ 
    var context = new ValidationContext(model); 
    var results = new List<ValidationResult>(); 
    Validator.TryValidateObject(model, context, results, true); 
    return results.Select(r => r.ErrorMessage); 
} 

更新

我原來忘了額外的true(validateAllProperties)在調用TryValidateObject結束。 true指定驗證器來檢查每個屬性和每個ValidationAttribute

我測試了這個對你的使用案例Lot = "a12345"哪些作品(不返回錯誤信息)v.s. Lot = "a1234$"這確實會返回一條錯誤消息。

希望這會有所幫助。

+0

對不起。忘了提及我在.net 3.5 – ASR