◷ Reading Time: 5 minutes
Assumptions
In the article Validation Hierarchy, we discussed how an inheritance relationship can be validated based on the concrete types of objects. Now consider a more complex model that has aggregation and composition as well. Assume in your application you have the following model:

In this model a contact may have more than one address and more than one number. We are going to extend the previous article`s rule to cover more validations.
Rules
In this article we are going to define the following rules:
- a contact must have at lease one address
- Address of a contact cannot be duplicated
- Phone of a contact cannot be duplicated
- Line1 property of each contact`s address can not be null or empty
Detecting duplication
When there is a collection, and the uniqueness of the items in the collection need to be validated, you can use UniqueConstraint command. This command enforces the uniqueness based on the combination of property values.
<Logic name="allAddressLine1_UniqueConstraint">
<And>
<UniqueConstraint>
<Add property="Line1"/>
<Add property="Line2"/>
</UniqueConstraint>
</And>
</Logic>
In this command, the combination of Line1 and Line2 must be unique in the contact`s address collection.
Validating collection
When there is a collection and a rule needs to be applied to each of the collection`s elements, ForEach can be used. This command will execute all its child rules against every element of the collection.
<Logic name="allAddressLine1_NotNullEmpty">
<And>
<ForEach childName="c">
<Null value="c.Line1" negate="true"/>
<Empty value="c.Line1" negate="true"/>
</ForEach>
</And>
</Logic>
childName will be the collection`s element reference for all the rules inside the ForEach
Minimum element of collection
One of the rules here is that a contact must have at least one address. To define this rule we can check the Count property of the collection by using Check.
We are going to add this rule to the logic named allAddressLine1_NotNullEmpty:
<Logic name="allAddressLine1_NotNullEmpty">
<And>
<!-- Minimum that one address must exist -->
<Check value="Count>0"/>
<!-- Line1 of address can not be null or empty -->
<ForEach childName="c">
<Null value="c.Line1" negate="true"/>
<Empty value="c.Line1" negate="true"/>
</ForEach>
</And>
</Logic>
Putting it all together
What is left now is to add these two extra logic into a validation rule and call them via contract logic?
<Logic name="Contact">
<And>
<Or>
<Validate logic="ValidatePersonContact">
<When>
<And>
<Contains value="Family"/>
<Contains value="Title"/>
</And>
</When>
</Validate>
<Validate logic="ValidateCompanyContact">
<When>
<And>
<Contains value="BusinessNumber"/>
</And>
</When>
</Validate>
</Or>
<Validate logic="allAddressLine1_NotNullEmpty" value="Addresses"/>
<Validate logic="allAddressLine1_UniqueConstraint" value="Addresses"/>
</And>
</Logic>
However, we need to put all the current logic of Contract into a And operator to get the aggregated result back when it is called.
Final rule
<Validation name="ContactRule">
<Logic name="Contact">
<And>
<Or>
<Validate logic="ValidatePersonContact">
<When>
<And>
<Contains value="Family"/>
<Contains value="Title"/>
</And>
</When>
</Validate>
<Validate logic="ValidateCompanyContact">
<When>
<And>
<Contains value="BusinessNumber"/>
</And>
</When>
</Validate>
</Or>
<Validate logic="allAddressLine1_NotNullEmpty" value="Addresses"/>
<Validate logic="allAddressLine1_UniqueConstraint" value="Addresses"/>
</And>
</Logic>
<Logic name="Person">
<Or negate="true">
<Validate logic="ValidString" value="Name"/>
<Validate logic="ValidString" value="Email"/>
</Or>
</Logic>
<Logic name="Company">
<Or negate="true">
<Validate logic="ValidString" value="Name"/>
<Validate logic="ValidString" value="Email"/>
<Validate logic="ValidString" value="BusinessNumber"/>
</Or>
</Logic>
<Logic name="ValidString" variable="str">
<And>
<Null value="str" />
<Empty value="str" />
</And>
</Logic>
<Logic name="allAddressLine1_NotNullEmpty">
<And>
<!-- Minimum an address must exists -->
<Check value="Count>0"/>
<!-- Line1 of address can not be null or empty -->
<ForEach childName="c">
<Null value="c.Line1" negate="true"/>
<Empty value="c.Line1" negate="true"/>
</ForEach>
</And>
</Logic>
<Logic name="allAddressLine1_UniqueConstraint">
<And>
<UniqueConstraint>
<Add property="Line1"/>
<Add property="Line2"/>
</UniqueConstraint>
</And>
</Logic>
</Validation>
Next sections
In the next couple of articles, we will cover different aspects of modeling and executing the validation rules using Validation logic.
- Introduction to validation rules
- Validating hierarchy (Inheritance relation)
- Validating association (Aggregation, Composition)
- Validation rule execution and collecting results
- Pass extra input values to validation rules
- Extending validation conditions and actions
- How to apply rules under some conditions
- Referencing commonly used logic
- Sample for Order processing validation logic