Conditional Validation
Apply validation rules based on conditions, data values, or business logic requirements.
What is Conditional Validation?
Conditional Validation in Validixty allows you to apply validation rules only when certain conditions are met. This is essential for complex business logic where validation requirements change based on user type, data values, or other contextual factors.
Why Use Conditional Validation?
- Business Logic: Different rules for different scenarios
- User Types: Vary validation based on user roles
- Data Dependencies: Validate based on other field values
- Progressive Validation: Apply rules as data becomes available
Before Using Validixty
Without conditional validation, complex business logic might look like this:
public ValidationResult ValidateOrder(Order order)
{
var errors = new List();
// Basic validation
if (string.IsNullOrEmpty(order.CustomerEmail))
errors.Add("Customer email is required");
if (order.OrderItems == null || !order.OrderItems.Any())
errors.Add("Order must have at least one item");
// Conditional validation based on customer type
if (order.CustomerType == CustomerType.Business)
{
if (string.IsNullOrEmpty(order.CompanyName))
errors.Add("Company name is required for business customers");
if (string.IsNullOrEmpty(order.TaxId))
errors.Add("Tax ID is required for business customers");
// Additional business rules
if (order.TotalAmount > 10000 && string.IsNullOrEmpty(order.ApprovalCode))
errors.Add("Approval code required for orders over $10,000");
}
else if (order.CustomerType == CustomerType.Individual)
{
if (order.TotalAmount > 5000)
errors.Add("Individual customers cannot order more than $5,000");
}
// Conditional validation based on payment method
if (order.PaymentMethod == PaymentMethod.CreditCard)
{
if (string.IsNullOrEmpty(order.CardNumber))
errors.Add("Credit card number is required");
if (order.CardExpiryDate < DateTime.Now)
errors.Add("Credit card has expired");
}
else if (order.PaymentMethod == PaymentMethod.BankTransfer)
{
if (string.IsNullOrEmpty(order.BankAccount))
errors.Add("Bank account is required for bank transfer");
}
return errors.Any() ? ValidationResult.Failure(string.Join("; ", errors))
: ValidationResult.Success();
}
After Using Validixty
With Validixty's Conditional Validation, the same logic becomes clean and maintainable:
using Validixty.Core;
public ValidationResult ValidateOrder(Order order)
{
return ConditionalValidation.ValidateWithCondition(order,
// Condition: Business customer
o => o.CustomerType == CustomerType.Business,
// Validator for business customers
Validation.For("Business Order")
.Check(x => !string.IsNullOrEmpty(x.CompanyName), "Company name required")
.Check(x => !string.IsNullOrEmpty(x.TaxId), "Tax ID required")
.Check(x => !(x.TotalAmount > 10000 && string.IsNullOrEmpty(x.ApprovalCode)),
"Approval code required for large orders"),
// Fallback validator for individual customers
Validation.For("Individual Order")
.Check(x => x.TotalAmount <= 5000, "Order limit exceeded for individual customers")
);
}
How It Saves Time
- Eliminates nested if statements: Clean, declarative conditions
- Reusable validators: Build condition-validator pairs
- Easier testing: Test conditions and validators separately
- Better readability: Clear business rule definitions
Usage Examples
Simple Conditional Validation
// Validate only if user is over 18
var ageValidation = ConditionalValidation.ValidateWithCondition(
user,
u => u.Age >= 18, // condition
new EmailAddressValidator(), // validator to apply
u => u.Email // value selector
);
Multiple Conditions with Different Validators
var paymentValidation = ConditionalValidation.ValidateWithConditions(user, new[]
{
// Credit card validation
new ConditionalRule(
p => p.Method == PaymentMethod.CreditCard,
Validation.For("Credit Card")
.CheckCreditCard(p => p.CardNumber)
.Check(x => x.ExpiryDate > DateTime.Now, "Card expired")),
// Bank transfer validation
new ConditionalRule(
p => p.Method == PaymentMethod.BankTransfer,
Validation.For("Bank Transfer")
.CheckIBAN(p => p.AccountNumber)
.Check(x => x.Amount >= 100, "Minimum transfer amount is $100")),
// Default validation for other methods
new ConditionalRule(
p => true, // Always true - fallback
Validation.For("Payment")
.Check(x => x.Amount > 0, "Amount must be positive"))
});
Complex Business Rules
// E-commerce order validation
var orderValidation = ConditionalValidation.ValidateWithCondition(order,
// Premium customer - relaxed rules
o => o.Customer.IsPremium,
Validation.For("Premium Order")
.Check(x => x.TotalAmount <= 50000, "Premium limit exceeded")
.CheckEmail(x => x.Customer.Email),
// Regular customer - strict rules
Validation.For("Regular Order")
.Check(x => x.TotalAmount <= 10000, "Order limit exceeded")
.CheckEmail(x => x.Customer.Email)
.CheckPhone(x => x.Customer.Phone)
.Check(x => x.Items.Count >= 1, "Order must have items")
);
Progressive Validation
// Validate as user fills the form
public ValidationResult ValidateRegistrationStep(UserRegistration user, int currentStep)
{
return ConditionalValidation.ValidateWithCondition(user,
// Step 1: Basic info
u => currentStep >= 1,
Validation.For("Basic Info")
.CheckName(u => u.FirstName)
.CheckName(u => u.LastName)
.CheckEmail(u => u.Email),
// Step 2: Security (only if step 1 passed)
ConditionalValidation.ValidateWithCondition(user,
u => currentStep >= 2,
Validation.For("Security")
.CheckPassword(u => u.Password)
.Check(x => x.Password == x.ConfirmPassword, "Passwords don't match"),
// Step 3: Additional info
ConditionalValidation.ValidateWithCondition(user,
u => currentStep >= 3,
Validation.For("Additional")
.CheckPhone(u => u.Phone)
.Check(x => x.AgreeToTerms, "Must agree to terms"),
Validation.For("Incomplete").Check(x => false, "Complete previous steps first")
)
)
);
}
Data-Driven Conditional Validation
// Configuration-driven validation
var config = new ValidationConfig
{
Rules = new[]
{
new ConditionalRule("LargeOrder",
o => o.TotalAmount > 1000,
Validation.For("Large Order").Check(x => !string.IsNullOrEmpty(x.ApprovalCode), "Approval required")),
new ConditionalRule("International",
o => o.IsInternational,
Validation.For("International").Check(x => !string.IsNullOrEmpty(x.ExportLicense), "Export license required")),
}
};
var result = ConditionalValidation.ValidateWithConfig(order, config);