This example shows how multiple [If]
attributes can be combined to create “OR” logic.
Suppose we have the following model
1
2
3
4
5
class CarColors
{
public string Interior { get; set; }
public string Exterior { get; set; }
}
Now let’s say that there is a requirement that if the exterior color is white or black, the interior needs to be gray; otherwise, the interior can be any color.
The standard way
In normal usage, we could create two condition groups: one for white and one for black. We would the apply constraints under those conditions.
1
2
3
4
5
6
7
8
9
[If(nameof(Exterior, "white", "isWhite"))]
[If(nameof(Exterior, "black", "isBlack"))]
class CarColors
{
[Const("gray", ConditionGroup = "isWhite")]
[Const("gray", ConditionGroup = "isBlack")]
public string Interior { get; set; }
public string Exterior { get; set; }
}
This would create the schema:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
{
"type": "object",
"properties": {
"Interior": { "type": "string" },
"Exterior": { "type": "string" }
},
"allOf": [
{
"if": {
"properties": {
"Exterior": { "const": "white" }
},
"required": [ "Exterior" ]
},
"then": {
"properties": {
"Interior": { "const": "gray" }
}
}
},
{
"if": {
"properties": {
"Exterior": { "const": "black" }
},
"required": [ "Exterior" ]
},
"then": {
"properties": {
"Interior": { "const": "gray" }
}
}
}
]
}
This is fine. But notice how the then
constraint sets are the same. It’d be better if the conditions could be combined to check if Exterior
is either "white"
or "black"
and just have a single then
.
Combining conditions
To do this, we just need to specify the same group in the appropriate [If]
attributes.
1
2
3
4
5
6
7
8
[If(nameof(Exterior, "white", "grayRequirement"))]
[If(nameof(Exterior, "black", "grayRequirement"))]
class CarColors
{
[Const("gray", ConditionGroup = "grayRequirement")]
public string Interior { get; set; }
public string Exterior { get; set; }
}
This will collect all of the possible values for that property and render them under an enum
instead of a const
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"type": "object",
"properties": {
"Interior": { "type": "string" },
"Exterior": { "type": "string" }
},
"allOf": [
{
"if": {
"properties": {
"Exterior": { "enum": [ "white", "black" ] }
},
"required": [ "Exterior" ]
},
"then": {
"properties": {
"Interior": { "const": "gray" }
}
}
}
]
}
This is a much more concise schema that better expresses the requirement.