复杂属性的 SetValidator 不起作用

本文关键字:不起作用 SetValidator 属性 复杂 | 更新日期: 2023-09-27 18:30:42

我有以下"费用"实体的验证类:

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 == 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.");
    }
}

和事务子类:

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

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

我使用以下命令验证费用对象:

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,当我为费用对象调用验证器时,它应该给我验证错误,因为它SetValidator()了事务属性,并且交易也不为空,因为我已经设置了new Transaction()

知道吗?

复杂属性的 SetValidator 不起作用

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

  • "说明"不应为空。
  • "金额"不得为空。
  • 企业 ID 是必需的。
  • 费用类型 ID 是必需的。
  • 员工 ID 是必需的。
  • "金额"不得为空。
  • "说明"不应为空。
  • "付款方式"不应为空。

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; }
    }
}