2011-09-29 71 views
3

我正在使用存儲庫模式編寫MVC應用程序。模型中的MVC驗證需要數據庫存儲庫

這是一個金融系統,其中有發票。我在發票模型中進行了驗證:

#region IValidatableObject Members 

     public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) 
     { 
      if ((TotalExcludingTax + (TotalExcludingTax * .15m)) != TotalIncludingTax) { 
       yield return new ValidationResult("The total (exc. Tax) + Tax does not equal the total (inc. Tax)."); 
      } 
     } 

     #endregion 

問題是稅率.15是可變的。目前它在這裏被硬編碼,並不是很好。我能想到這樣做的唯一方法是:

#region IValidatableObject Members 

     public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) 
     { 
      var taxRepository = new Repository<tax>(); 

      if ((TotalExcludingGst + (TotalExcludingGst * taxRepository.GetCurrentTaxRate())) != TotalIncludingGst) { 
       yield return new ValidationResult("The total (exc. Gst) + Gst does not equal the total (inc. Gst)."); 
      } 
     } 

     #endregion 

使用這種方法我現在實例發票模型內的taxRepository實例。

這是不好的做法?

有沒有更好的方法來做到這一點?

回答

3

是的,你現在的做法並不好,這正是FluentValidator的設計方案。

舉個例子,在我們的對象之一,我們有需要複雜的規則,以確定是否郵政編碼是有效的,所以我們做這樣的事有些郵編驗證:

public class AddressValidator : AbstractValidator<Address> 
{ 
    private readonly IPostCodeRepository _postcodeRepo; 

    public AddressValidator(IPostCodeRepository postcodeRepo) 
    { 
     _postcodeRepo = postcodeRepo; 

     RuleFor(a => a.Postcode) 
       .NotEmpty() 
       .WithMessage("Postcode is required") 
       .Must(BeValidPostcodeSuburbStateCombo) 
       .WithMessage("Postcode is not valid for this state"); 
    } 

    private bool BeValidPostcodeSuburbStateCombo(Address model, string property) 
    { 
     return _postcodeRepo.ValidatePostcode(model.Postcode, model.Suburb, model.State); 
    } 
} 

這種方法的好處是,它使您的模型保持乾淨整潔,並允許您驗證複雜的邏輯。

如果切換到FluentValidator不是您的選擇,我會建議在稱爲TaxRate的模型上添加一個附加屬性,並在調用Validate方法之前設置它。

這並不理想,但這意味着您沒有在模型中的存儲庫中使用依賴項。

+1

是_postcodeManager假設是_postcodeRepo? – Ryan