2011-09-29 88 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