模型中的MVC验证需要数据库存储库

时间:2011-09-29 20:43:19

标签: asp.net-mvc validation repository-pattern

我正在使用存储库模式编写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实例。

这是不好的做法吗?

有更好的方法吗?

1 个答案:

答案 0 :(得分:3)

是的,您当前的方法并不是很好,这正是构建FluentValidator的方案。

例如,在我们的一个对象中,我们有一些PostCode验证需要复杂的规则来确定邮政编码是否有效所以我们这样做:

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方法之前设置它。

这并不理想,但这意味着您不会在模型中的存储库中依赖。