I have this model
public class Person
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName
Try this
RuleFor(person => person).Must(person => !string.IsNullOrEmpty(person.FirstName) || !string.IsNullOrEmpty(person.LastName))
A nice rule-set to check if one of two fields are empty, as well as coming up with meaningful error codes is the following:
public CustomerSourceValidator()
{
CascadeMode = CascadeMode.StopOnFirstFailure;
RuleFor(x => x)
.NotNull().WithErrorCode("source_id_or_email_required")
.When(source => source.Email == null && source.Id == null);
RuleFor(x => x.Id)
.NotNull().WithErrorCode("source_id_required")
.Matches(CommonValidationRegex.CustomerIdRegexString).WithErrorCode("source_id_invalid")
.When(source => source.Id != null);
RuleFor(x => x.Email)
.NotNull().WithErrorCode("source_email_required")
.Matches(CommonValidationRegex.EmailRegexString).WithErrorCode("source_email_invalid")
.When(source => source.Email != null);
}
I did like this to check charges entered are same to previous one or not. If charges are same as previous one than it'll give an error. This worked for me.
public class CasualMealChargeValidator : AbstractValidator<CasualMealCharge>
{
public CasualMealChargeValidator(CasualMealCharge CMC)
{
//RuleFor(x => x.BankName).NotEmpty().When(pm => pm.PaymentMode == "Cheque").WithMessage("Enter Bank.");
RuleFor(x => x).Must(x => x.DN != CMC.DN || x.BF != CMC.BF || x.LN != CMC.LN).WithMessage("Not Saved - Meal charges are same as current charges.").WithName("CMFor");
}
}
Finally, this worked for me. I wanted to validate three properties where at least one is required. It returns an error message only once.
RuleFor(p => p).Cascade(CascadeMode.StopOnFirstFailure)
.Must(p => !string.IsNullOrWhiteSpace(p.FirstName))
.When(p => p.Id == 0 && string.IsNullOrWhiteSpace(p.LastName)).WithMessage("At least one is required (Id, FirstName, LastName).")
.Must(p => !string.IsNullOrWhiteSpace(p.LastName))
.When(p => p.Id == 0 && string.IsNullOrWhiteSpace(p.FirstName)).WithMessage("At least one is required (Id, FirstName, LastName).")
.Must(p => p.Id != 0)
.When(p => string.IsNullOrWhiteSpace(p.FirstName) && string.IsNullOrWhiteSpace(p.LastName)).WithMessage("At least one is required (Id, FirstName, LastName).");
I don't know that library, but if you just want to check those two properties for null, then you can use this:
RuleFor(person => person.FirstName ?? person.LastName).NotNull();
EDIT This doesn't work, because it throws an InvalidOperationException
. Use Zabavsky's solution instead.
You can use When/Unless condition:
RuleFor(m => m.FirstName).NotEmpty().When(m => string.IsNullOrEmpty(m.LastName));
RuleFor(m => m.LastName).NotEmpty().When(m => string.IsNullOrEmpty(m.FirstName));
or
RuleFor(m => m.FirstName).NotEmpty().Unless(m => !string.IsNullOrEmpty(m.LastName));
RuleFor(m => m.LastName).NotEmpty().Unless(m => !string.IsNullOrEmpty(m.FirstName));
As for your second question, FluentValidation
works with client-side validation, but not all rules are supported. Here you can find validators, that are supported on the client-side:
For rules that are not in the list you have to write your own FluentValidationPropertyValidator
and implement GetClientValidationRules
. You can find a few samples of this on the StackOverflow by doing simple search.