FluentValidation Check if one of two fields are empty
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
A common validation rule is "at least one of these two fields must be provided." In FluentValidation, that is usually best expressed as an object-level rule, because the condition depends on more than one property at the same time. Once you frame it that way, the implementation becomes straightforward and easy to test.
Model And Validation Goal
Suppose a request is valid if the user provides either an email address or a phone number.
The business rule is:
- email can be present
- phone number can be present
- both can be present
- but both cannot be missing or whitespace
That rule spans the whole object, not a single field.
Use RuleFor(x => x) With Must
The cleanest FluentValidation pattern is an object-level rule.
This works because RuleFor(x => x) lets the predicate inspect the entire object.
It is usually better than attaching the rule to only one property, because the error message clearly describes a relationship between fields rather than pretending one field is solely responsible.
Add Field-Specific Rules Too
Cross-field validation does not replace normal field validation. You can still validate format only when a field is present.
That keeps the intent clear:
- one rule ensures at least one field exists
- another rule checks the format of the optional email when it is supplied
If You Mean "Exactly One" Instead Of "At Least One"
Sometimes the real requirement is different: exactly one of the two fields must be filled, not both. That logic needs a different predicate.
This is a good reminder to state the business rule precisely before writing the validator. "One of two fields" can mean two different things in real systems.
Testing The Validator
Because this logic is cross-field, unit tests are especially useful.
Testing both valid and invalid combinations helps prevent regressions when the validator grows.
Common Pitfalls
The most common mistake is attaching the rule to only one property with RuleFor(x => x.Email) and then trying to inspect the other field indirectly. That usually produces awkward messages and unclear intent.
Another issue is forgetting to treat whitespace-only strings as empty. string.IsNullOrWhiteSpace is usually the right choice here.
It is also easy to confuse "at least one" with "exactly one." Those are different business rules and need different predicates.
Finally, do not stop at the cross-field rule if the individual fields have their own format requirements. Presence and format are separate concerns.
Summary
- Use an object-level FluentValidation rule when the condition depends on multiple fields.
- '
RuleFor(x => x).Must(...)is the cleanest way to express "at least one field is required."' - Keep format validation separate from cross-field presence checks.
- Be explicit about whether the rule means "at least one" or "exactly one."
- Test multiple field combinations so the validator stays trustworthy.
Related reading
- Flutter - Default image to Image.network when it fails
- force browsers to get latest js and css files in asp.net application
- Force XmlSerializer to serialize DateTime as 'YYYY-MM-DD hhmmss
- Formatting IPv6 as an int in C and storing it in SQL Server
- Func delegate with no return type
- Func vs. Action vs. Predicate
- FuncT with out parameter
- Fuzzy text sentences/titles matching in C

OOD Fundamentals
Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.