How to construct an annotation from a term definition, or re-engineer a term definition from an annotation example?
Here's how.
Terms are defined within a "vocabulary", which is just an EDMX document.
{
"$Version": "4.0",
"Vocab": {
To use a term in an annotation, the vocabulary of the term needs to be referenced and included.
{
"$Version": "4.0",
"$Reference": {
"https://somewhere.org/vocab.xml": {
"$Include": [
{
"$Namespace": "Vocab"
}
]
}
}
If the term has a primitive type
"StringTerm": {
"$Kind": "Term"
}
A constant annotation value can be provided as a corresponding JSON value.
"@Vocab.StringTerm": "annotation value"
See Constant Annotation Values for a list of all primitiv types and example values for them.
A dynamic annotation value can be provided for the same term using a value path expression.
"@Vocab.StringTerm": {
"$Path": "SomeStringProperty"
}
The property referenced via the value path expression, here SomeStringProperty
needs to have the same type as the term. A value path expression can always be used instead of a constant value, also in the more complicated cases below.
If the term has a collection type
"CollectionTerm": {
"$Kind": "Term",
"$Collection": true,
"$Type": "Edm.Decimal"
}
the annotation value is provided as a collection expression
"@Vocab.CollectionTerm": [
2.78,
3.14
]
Note: decimal values can also be represented as strings to prevent loss of precision in JavaScript clients.
If the term has a structured type
"StructuredTerm": {
"$Kind": "Term",
"$Type": "Vocab.Complex"
},
"Complex": {
"$Kind": "ComplexType",
"IntegerField": {
"$Type": "Edm.Int32"
}
}
the annotation value is provided as a record expression
"@Vocab.StructuredTerm": {
"IntegerField": 42
}
Constant annotation values for primitive properties are provided in the same way as for primitive terms.
Terms can also be typed as a collection of a structured type.
"StructuredCollectionTerm": {
"$Kind": "Term",
"$Collection": true,
"$Type": "Vocab.AnotherComplex"
},
"AnotherComplex": {
"$Kind": "ComplexType",
"DateField": {
"$Type": "Edm.Date",
"$Nullable": true
},
"TimeField": {
"$Type": "Edm.TimeOfDay",
"$DefaultValue": "00:00:00"
}
}
The annotation value is provided as a collection of records.
"@Vocab.StructuredCollectionTerm": [
{
"DateField": "2020-06-30",
"TimeField": "16:55:03"
},
{
"DateField": "2020-07-01"
},
{
"TimeField": "23:59:59"
}
]
Properties that are nullable or have a default value can be omitted.
Properties of a structured type can themselves be structured or collections.
"NestedTerm": {
"$Kind": "Term",
"$Collection": true,
"$Type": "Vocab.YetAnotherComplex",
},
"YetAnotherComplex": {
"StructuredField": {
"$Type": "Vocab.Complex"
},
"CollectionField": {
"$Collection": true,
"$Type": "Vocab.AnotherComplex"
}
}
The property value is provided as a record or collection.
"@Vocab.NestedTerm": {
"StructuredField": {
"IntegerField": 42
},
"CollectionField": [
{
"DateField": "2020-06-30",
"TimeField": "16:55:03"
}
]
}
The name of the attribute to provide a constant annotation value depends on the type of the term or term property.
Type of Term or Term Property | Example Value |
---|---|
Edm.Binary |
"T0RhdGE" |
Edm.Boolean |
true |
Edm.Date |
"2000-01-01" |
Edm.DateTimeOffset |
"2000-01-01T16:00:00.000Z" |
Edm.Decimal |
"3.14" |
Edm.Duration |
"P7D" |
Enumeration Type | "Red" |
Edm.Double or Edm.Single |
3.14 |
Edm.Guid |
"21EC2020-3AEA-1069-A2DD-08002B30309D" |
Edm.Int16 , Edm.Int32 , Edm.64 , Edm.Byte , Edm.SByte |
42 |
Edm.Int64 |
"42" |
Edm.String |
"annotation value" |
Edm.TimeOfDay |
"21:45:00" |
Edm.AnnotationPath |
"Product/Supplier/@UI.LineItem" |
Edm.NavigationPropertyPath |
"Supplier" |
Edm.PropertyPath |
"Details/ChangedAt" |