2017-04-08 67 views
0

我試圖編寫自定義ValidationAttribute,驗證沒有記錄已存在具有相同值。自定義驗證屬性:如何檢查重複值,忽略正在編輯的對象

的問題是,如果用戶正在編輯現有記錄,那麼我的代碼找到一個相匹配的相同值的記錄。如果用戶沒有更改該值,它將找到正在編輯的那個。

所以我想我可以在ValidationContext.ObjectInstance的值進行比較的值來檢測時,它並沒有改變,這樣的事情:

public class UrlTagValidationAttribute : ValidationAttribute 
{ 
    protected override ValidationResult IsValid(object value, ValidationContext context) 
    { 
     string tag = value as string; 
     if (string.IsNullOrWhiteSpace(tag)) 
      return new ValidationResult("URL Tag is required."); 

     // We allow a valid that is equal to the original value 
     if (context.ObjectInstance is TrainerModel model && model.Tag == tag) 
      return ValidationResult.Success; 

     // Cannot be an existing tag 
     using (var dbContext = new OnBoard101Entities()) 
     { 
      if (!dbContext.TrainerDetails.Any(td => td.Tag == tag)) 
       return ValidationResult.Success; 
     } 

     return new ValidationResult("This URL Tag is not available. Please enter a different one."); 
    } 
} 

但是,這是行不通的。我發現ValidationContext.ObjectInstance中的值通常與我創建新記錄時輸入的值相匹配。

我很難找到關於ValidationContext當前使用情況的良好和最新的文檔。有人可以提出一種方法來檢查是否存在任何與輸入值匹配的記錄,但是當正在編輯記錄並且該字段的值沒有改變時允許它?

回答

0

當前正在編輯的項目很可能具有某種屬性以識別它(在數據庫中查找它)。因此,您需要獲取該屬性,以便在搜索數據庫中查找重複標記時排除該屬性。這是如何在你的自定義驗證類中做到這一點。我假設標識符名爲TrainerId

public class UrlTagValidationAttribute : ValidationAttribute 
{ 
    protected override ValidationResult IsValid(object value, ValidationContext context) 
    { 
     string tag = value as string; 
     if(string.IsNullOrWhiteSpace(tag)) 
      return new ValidationResult("URL Tag is required."); 

     var currentTrainer = validationContext.ObjectInstance 
           as TrainerModel; 
     if (currentTrainer == null) 
     { 
      // What do you want to do? You cannot always return an error 
      // because another type could be using this custom validation. 
      // Or you can return an error. Depends on your requirements and 
      // and usage. 
     } 
     using(var dbContext = new OnBoard101Entities()) 
     { 
      if(dbContext.TrainerDetails.Any(td => td.Tag == tag && td.TrainerId != 
              currentTrainer.TrainerId)) 
      { 
       return new ValidationResult("This URL Tag is not available. Please enter a different one."); 
      } 
     } 

     return ValidationResult.Success; 
    } 
} 
+0

這是我最終採取的方法。請注意,您應該使用'validationContext.ObjectInstance作爲TrainerModel',然後檢查'null'的結果以確保安全。在不太可能的情況下,它是'null',我返回一個錯誤。 –

+0

是的,我想你會照顧錯誤處理。 – CodingYoshi

相關問題