SetValidator用于复杂属性不起作用

时间:2013-09-07 21:44:52

标签: c# fluentvalidation

我有“Expense”实体的以下验证类:

public class ExpenseBaseValidator : AbstractValidator<Expense>
{
    public ExpenseBaseValidator()
    {
        RuleFor(x => x.Description).NotEmpty();
        RuleFor(x => x.Amount).NotNull();
        RuleFor(x => x.BusinessID).NotEqual(0).WithMessage("BusinessID is required.");
        RuleFor(x => x.ExpenseTypeID).NotEqual(0).WithMessage("ExpenseTypeID is required.");
        RuleFor(x => x.CreatedDate).NotNull();
        RuleFor(x => x.Transaction).SetValidator(new TransactionValidator());
    }
}

然后我有Transaction的验证类,它是上面Expense类中的复杂属性:

public class TransactionBaseValidator : AbstractValidator<Transaction>
{
    public TransactionBaseValidator()
    {
        RuleFor(x => x.BankAccountID).NotEqual(0).WithMessage("BankAccountID is required.");
        RuleFor(x => x.EmployeeID).NotEqual(0).WithMessage("EmployeeID is required.");
        RuleFor(x => x.TransactionDate).NotNull();
        RuleFor(x => x.IsWithdrawal).NotNull();
        RuleFor(x => x.Amount).NotNull();
        RuleFor(x => x.Description).NotEmpty();
        RuleFor(x => x.PaymentMethod).NotEmpty();
        RuleFor(x => x.PaymentMethod).Length(0, 50).WithMessage("PaymentMethod can not exceed 50 characters");
    }
}

现在这些是基类,我分别使用以下子类调用验证器:

public class ExpenseValidator : ExpenseBaseValidator
{
    public ExpenseValidator()
        : base()
    {
        RuleFor(x => x.Transaction)
            .NotNull()
            .When(x => x.IsPaid == true)
            .WithMessage("An account transaction is required when the amount is paid.");

        RuleFor(x => x.DatePaid)
            .NotNull()
            .When(x => x.IsPaid == true)
            .WithMessage("Please enter the date when the expense was paid.");
    }
}

和Transaction子类:

public class TransactionValidator : TransactionBaseValidator
{
    public TransactionValidator() : base()
    {

    }
}

这些可以有额外的验证规则,并且使用base()构造函数调用基本规则。

我使用以下方法验证Expense对象:

var validator = new ExpenseValidator();
var results = validator.Validate(oExpense);

现在,这不会返回我正在使用的复杂属性事务的验证:

oExpense.Transaction = new Transaction();
oExpense.Transaction.Amount = oExpense.Amount;
oExpense.Transaction.BankAccountID = ddlAccounts.SelectedItem.Value.ToInt();
oExpense.Transaction.TransactionDate = oExpense.DatePaid.Value;
oExpense.Transaction.IsWithdrawal = true;
oExpense.Transaction.Description = oExpense.Description;
oExpense.Transaction.IsDeleted = false;
// I dont set the below and it should give me validation error:
// oExpense.Transaction.EmployeeID = 10;

我没有设置EmployeeID,当我为cost对象调用validator时它应该给我验证错误,因为它对Transaction属性有SetValidator()而且Transaction也不是null,因为我已经设置{{1 }}

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我使用了您发布的验证,并根据验证器中包含的内容创建了相关的类/属性。从发布的示例中构建Transaction对象,我收到以下验证错误:

  • &#39;说明&#39;不应该是空的。
  • &#39;量&#39;不能为空。
  • 需要BusinessID。
  • ExpenseTypeID是必需的。
  • 需要EmployeeID。
  • &#39;量&#39;不能为空。
  • &#39;说明&#39;不应该是空的。
  • &#39;付款方式&#39;不应该是空的。

var results = validator.Validate(oExpense);上放置一个断点并验证oExpense.Transaction.EmployeeID的值。 如果该值不为0,则在其他位置设置EmployeeID

供参考,这是我创建的基本控制台应用程序:

using System;
using System.Linq;
using FluentValidation;
using FluentValidation.Results;

namespace so.FluentValidationComplexProperties
{
    internal class Program
    {
        private static void Main( string[] args )
        {
            var oExpense = new Expense();
            oExpense.Transaction = new Transaction();
            oExpense.Transaction.Amount = oExpense.Amount;
            oExpense.Transaction.BankAccountID = 10;
            oExpense.Transaction.TransactionDate = DateTime.Today;
            oExpense.Transaction.IsWithdrawal = true;
            oExpense.Transaction.Description = oExpense.Description;
            oExpense.Transaction.IsDeleted = false;
            // I dont set the below and it should give me validation error:
            // oExpense.Transaction.EmployeeID = 10;


            var validator = new ExpenseValidator();
            ValidationResult results = validator.Validate( oExpense );

            results.Errors.ToList().ForEach( Console.WriteLine );

            Console.WriteLine();
            Console.Write( "--done--" );
            Console.WriteLine();
            Console.ReadLine();
        }
    }


    public class ExpenseBaseValidator : AbstractValidator<Expense>
    {
        public ExpenseBaseValidator()
        {
            RuleFor( x => x.Description ).NotEmpty();
            RuleFor( x => x.Amount ).NotNull();
            RuleFor( x => x.BusinessID ).NotEqual( 0 ).WithMessage( "BusinessID is required." );
            RuleFor( x => x.ExpenseTypeID ).NotEqual( 0 ).WithMessage( "ExpenseTypeID is required." );
            RuleFor( x => x.CreatedDate ).NotNull();
            RuleFor( x => x.Transaction ).SetValidator( new TransactionValidator() );
        }
    }

    public class TransactionBaseValidator : AbstractValidator<Transaction>
    {
        public TransactionBaseValidator()
        {
            RuleFor( x => x.BankAccountID ).NotEqual( 0 ).WithMessage( "BankAccountID is required." );
            RuleFor( x => x.EmployeeID ).NotEqual( 0 ).WithMessage( "EmployeeID is required." );
            RuleFor( x => x.TransactionDate ).NotNull();
            RuleFor( x => x.IsWithdrawal ).NotNull();
            RuleFor( x => x.Amount ).NotNull();
            RuleFor( x => x.Description ).NotEmpty();
            RuleFor( x => x.PaymentMethod ).NotEmpty();
            RuleFor( x => x.PaymentMethod ).Length( 0, 50 ).WithMessage( "PaymentMethod can not exceed 50 characters" );
        }
    }

    public class ExpenseValidator : ExpenseBaseValidator
    {
        public ExpenseValidator()
                : base()
        {
            RuleFor( x => x.Transaction )
                    .NotNull()
                    .When( x => x.IsPaid )
                    .WithMessage( "An account transaction is required when the amount is paid." );

            RuleFor( x => x.DatePaid )
                    .NotNull()
                    .When( x => x.IsPaid )
                    .WithMessage( "Please enter the date when the expense was paid." );
        }
    }

    public class TransactionValidator : TransactionBaseValidator
    {
        public TransactionValidator()
                : base() {}
    }


    public class Expense
    {
        public string Description { get; set; }
        public decimal? Amount { get; set; }
        public int BusinessID { get; set; }
        public int ExpenseTypeID { get; set; }
        public DateTime CreatedDate { get; set; }
        public Transaction Transaction { get; set; }
        public bool IsPaid { get; set; }
        public DateTime DatePaid { get; set; }
    }

    public class Transaction
    {
        public int BankAccountID { get; set; }
        public int EmployeeID { get; set; }
        public DateTime TransactionDate { get; set; }
        public bool? IsWithdrawal { get; set; }
        public decimal? Amount { get; set; }
        public string Description { get; set; }
        public string PaymentMethod { get; set; }
        public bool IsDeleted { get; set; }
    }
}