2009-06-22 45 views
0

假設我有兩個字段的實體。某些特定狀態需要某些字段,而另一些字段僅限於其他狀態。使用不同場景的實體驗證

public class Entity 
{ 
    //Required always 
    public SomeReference {} 

    //Required in specific situation/scenario 
    public OtherReference {} 
} 

如何用一些已知的驗證框架來實現這個場景或者如何通過我自己來實現?

尋求幫助: Udi Dahan對此有一些想法。 http://www.udidahan.com/2007/04/30/generic-validation/

回答

0

我的優先考慮是將通用的驗證功能(如電子郵件和日期驗證)本地化到ValidationService類中,以便將對象傳入。儘管我傾向於將驗證放入課堂本身。如果我使用LINQ to SQL然後我可以創建對象上的validate()方法,LINQ到SQL會先打電話到該對象保存到數據庫是這樣的:在這裏閱讀的充分理解

public void Validate() 
{ 
    if(!IsValid) 
     throw new ValidationException("Rule violations prevent saving"); 
} 

public bool IsValid 
{ 
    get { return GetRuleViolations().Count() == 0;} 
} 

public IEnumerable<RuleViolation> GetRuleViolations() 
{ 
    if(this.TermID == 0) 
     yield return new RuleViolation(HelpMessageService.GetHelpMessageBodyByID(1), "agreeWithTerms"); 

    if(ValidationService.ValidateDate(this.Birthdate.ToString())) 
     yield return new RuleViolation(HelpMessageService.GetHelpMessageBodyByID(2), "birthDate"); 

    if (!(Username.Length >= ConfigurationService.GetMinimumUsernameLength()) || 
     !(Username.Length <= ConfigurationService.GetMaximumUsernameLength())) 
     yield return new RuleViolation(HelpMessageService.GetHelpMessageBodyByID(5), "username"); 

    if(ValidationService.ValidateUsernameComplexity(Username)) 
     yield return new RuleViolation(HelpMessageService.GetHelpMessageBodyByID(6), "username"); 

    if (AccountID == 0 && ObjectFactory.GetInstance<IAccountRepository>().UsernameExists(this.Username)) 
     yield return new RuleViolation(HelpMessageService.GetHelpMessageBodyByID(7), "username"); 

    if (!ValidationService.ValidateEmail(Email)) 
     yield return new RuleViolation(HelpMessageService.GetHelpMessageBodyByID(8), "email"); 

    if (AccountID == 0 && ObjectFactory.GetInstance<IAccountRepository>().EmailExists(this.Email)) 
     yield return new RuleViolation(HelpMessageService.GetHelpMessageBodyByID(9), "email"); 

    yield break; 
} 

這個:http://nerddinnerbook.s3.amazonaws.com/Part3.htm

1

我有一個解決方案,目前我正在使用。我使用Fluent validation,我仍然習慣它。我可以給你一個簡單場景的例子。也許它有幫助。我有一個用戶類,具有一個地址對象屬性。在某些時候,我只想驗證用戶的詳細信息(姓名,電子郵件,密碼等),並在另一個州想驗證用戶地址(第一行,郵政編碼等)。

類是這樣的:

public class User { 
    public virtual string Name { get; set; } 
    public virtual string Email { get; set; } 
    public virtual string Password { get; set; } 
    public virtual Address Address { get; set; }   
} 

public class Address { 
    public virtual string Address1 { get; set; } 
    public virtual string PostCode { get; set; } 
} 

然後我有兩個(simplfied)驗證,一個地址和一個用於用戶:

public AddressValidator() { 
     RuleFor(address => address.Address1) 
      .NotNull() 
      .WithMessage("Please enter the first line of your address"); 

     RuleFor(address => address.PostCode) 
      .NotNull() 
      .WithMessage("Please enter your postcode") 
      .Matches(UK_POSTCODE_REGEX) 
      .WithMessage("Please enter a valid post code!"); 
    } 

    public UserValidator() { 
     RuleFor(user => user.FirstName) 
      .NotNull() 
      .WithMessage("Please provide a first name") 
      .Length(3, 50) 
      .WithMessage("First name too short"); 

     RuleFor(user=> user.Password) 
      .Length(8, 50) 
      .WithMessage("Password is too short"); 
    } 

然後我創建了一個模型驗證,所以例如,假設我們有一個用戶輸入地址的表單,我們創建一個AddressModelValidator,並且可以重新使用我們所寫的驗證器:

public AddressModelValidator() { 
     RuleFor(user => user.id) 
      .NotNull() 
      .WithMessage("An error has occured, please go back and try again"); 

     RuleFor(user => user.Address).SetValidator(new AddressValidator()); 
    } 

所以,有些想法,你真的可以創建一些不錯的模型,並減少驗證碼重複!

+0

這很接近,但一個對象具有不同的狀態呢? – dariol 2010-01-18 00:13:40