Skip to content

Commit 6ac465d

Browse files
authored
Adds @odata.type property and makes this a required property in schemas that have discriminator objects (#246)
* Add @odata.type property to Properties object and set default value * Update tests * Updates release notes * Move value to a const outside the method * PR review suggestion; throw exception when property exists in schema
1 parent bdf4241 commit 6ac465d

File tree

4 files changed

+39
-5
lines changed

4 files changed

+39
-5
lines changed

src/Microsoft.OpenApi.OData.Reader/Common/Constants.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,5 +109,10 @@ internal static class Constants
109109
/// Name used for reference update.
110110
/// </summary>
111111
public static string ReferenceUpdateSchemaName = "ReferenceUpdateSchema";
112+
113+
/// <summary>
114+
/// The odata type name.
115+
/// </summary>
116+
public static string OdataType = "@odata.type";
112117
}
113118
}

src/Microsoft.OpenApi.OData.Reader/Generator/OpenApiSchemaGenerator.cs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ public static IDictionary<string, OpenApiSchema> CreateSchemas(this ODataContext
102102
Properties = new Dictionary<string, OpenApiSchema>
103103
{
104104
{"@odata.id", new OpenApiSchema { Type = "string", Nullable = false }},
105-
{"@odata.type", new OpenApiSchema { Type = "string", Nullable = true }},
105+
{Constants.OdataType, new OpenApiSchema { Type = "string", Nullable = true }},
106106
}
107107
};
108108
}
@@ -449,13 +449,13 @@ private static OpenApiSchema CreateStructuredTypeSchema(this ODataContext contex
449449

450450
discriminator = new OpenApiDiscriminator
451451
{
452-
PropertyName = "@odata.type",
452+
PropertyName = Constants.OdataType,
453453
Mapping = mapping
454454
};
455455
}
456456

457457
// A structured type without a base type is represented as a Schema Object of type object
458-
OpenApiSchema schema = new OpenApiSchema
458+
OpenApiSchema schema = new()
459459
{
460460
Title = (structuredType as IEdmSchemaElement)?.Name,
461461

@@ -473,6 +473,20 @@ private static OpenApiSchema CreateStructuredTypeSchema(this ODataContext contex
473473
AnyOf = null
474474
};
475475

476+
if (schema.Discriminator != null)
477+
{
478+
if (!schema.Properties.TryAdd(Constants.OdataType, new OpenApiSchema()
479+
{
480+
Type = "string",
481+
Default = new OpenApiString("#" + structuredType.FullTypeName()),
482+
}))
483+
{
484+
throw new InvalidOperationException(
485+
$"Property {Constants.OdataType} is already present in schema {structuredType.FullTypeName()}; verify CSDL.");
486+
}
487+
schema.Required.Add(Constants.OdataType);
488+
}
489+
476490
// It optionally can contain the field description,
477491
// whose value is the value of the unqualified annotation Core.Description of the structured type.
478492
if (structuredType.TypeKind == EdmTypeKind.Complex)
@@ -559,7 +573,7 @@ private static IOpenApiAny GetTypeNameForExample(ODataContext context, IEdmTypeR
559573
case EdmTypeKind.Complex:
560574
case EdmTypeKind.Enum:
561575
OpenApiObject obj = new OpenApiObject();
562-
obj["@odata.type"] = new OpenApiString(edmTypeReference.FullName());
576+
obj[Constants.OdataType] = new OpenApiString(edmTypeReference.FullName());
563577
return obj;
564578

565579
case EdmTypeKind.Collection:

src/Microsoft.OpenApi.OData.Reader/Microsoft.OpenAPI.OData.Reader.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<TargetFrameworks>netstandard2.0</TargetFrameworks>
1616
<PackageId>Microsoft.OpenApi.OData</PackageId>
1717
<SignAssembly>true</SignAssembly>
18-
<Version>1.0.11-preview3</Version>
18+
<Version>1.0.11-preview4</Version>
1919
<Description>This package contains the codes you need to convert OData CSDL to Open API Document of Model.</Description>
2020
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
2121
<PackageTags>Microsoft OpenApi OData EDM</PackageTags>
@@ -27,6 +27,7 @@
2727
- Fixes missing bound operations on some navigation property paths #201
2828
- Provides support for using success status code range 2XX #153
2929
- Adds discriminator object to complex types which have derived types #233
30+
- Adds @odata.type property and makes this a required property in schemas that have discriminator objects #243
3031
</PackageReleaseNotes>
3132
<AssemblyName>Microsoft.OpenApi.OData.Reader</AssemblyName>
3233
<AssemblyOriginatorKeyFile>..\..\tool\Microsoft.OpenApi.OData.snk</AssemblyOriginatorKeyFile>

test/Microsoft.OpenAPI.OData.Reader.Tests/Generator/OpenApiSchemaGeneratorTests.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,20 @@ public void CreateStructuredTypeSchemaForEntityTypeWithDiscriminatorValueEnabled
106106
},
107107
{
108108
""title"": ""directoryObject"",
109+
""required"": [
110+
""@odata.type""
111+
],
109112
""type"": ""object"",
110113
""properties"": {
111114
""deletedDateTime"": {
112115
""pattern"": ""^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$"",
113116
""type"": ""string"",
114117
""format"": ""date-time"",
115118
""nullable"": true
119+
},
120+
""@odata.type"": {
121+
""type"": ""string"",
122+
""default"": ""#microsoft.graph.directoryObject""
116123
}
117124
},
118125
""discriminator"": {
@@ -163,11 +170,18 @@ public void CreateStructuredTypeSchemaForComplexTypeWithDiscriminatorValueEnable
163170
Assert.NotNull(json);
164171
Assert.Equal(@"{
165172
""title"": ""userSet"",
173+
""required"": [
174+
""@odata.type""
175+
],
166176
""type"": ""object"",
167177
""properties"": {
168178
""isBackup"": {
169179
""type"": ""boolean"",
170180
""nullable"": true
181+
},
182+
""@odata.type"": {
183+
""type"": ""string"",
184+
""default"": ""#microsoft.graph.userSet""
171185
}
172186
},
173187
""discriminator"": {

0 commit comments

Comments
 (0)