OData / odata.net

ODataLib: Open Data Protocol - .NET Libraries and Frameworks
https://docs.microsoft.com/odata
Other
686 stars 349 forks source link

OData8: No way to get top level annotation #3026

Open fmaeseele opened 3 months ago

fmaeseele commented 3 months ago

Cannot get top level annotation from IEdmModel using ODataMessageReader.ReadMetadataDocument method.

Assemblies affected

Microsoft.OData.Core lib 7.x, 8.x Microsoft.OData.Edm lib 7.x, 8.x

Reproduce steps

Consider this OData metadata content:

{
  "$Version": "4.01",
  "Flows": {
    "Flow0": {
      "$Kind": "EntityType",
      "$Key": [ "Id" ],
      "Id": {
        "$Type": "Edm.Int32",
        "$Nullable": false
      },
      "State": {
        "$Type": "Edm.String",
        "@sap.label": "State",
        "@sap.objectKey": "DP0.DO29",
        "@sap.qualification": "DIMENSION"
      },
      "Salesrevenue": {
        "$Type": "Edm.Double",
        "@sap.label": "Sales revenue",
        "@sap.objectKey": "DP0.DO3e",
        "@sap.qualification": "MEASURE",
        "@sap.projectionFunction": "Sum"
      }
    },
    "Flows": {
      "$Kind": "EntityContainer",
      "Flows0": {
        "$Kind": "EntitySet",
        "$Type": "Flows.Flow0"
      }
    },
    "@sap.isPartial": false
  }
}

I Cannot get the @sap.isPartial annotation from IEdmModel obtained by using the following code:

        using var odataEdmModelReader = new ODataMessageReader((IODataResponseMessage)odataInMemoryMetadataStream, ODataReaderSettings);
        var settings = new CsdlJsonReaderSettings()
        {
            IgnoreUnexpectedJsonElements = true,
        };
        var odataEdmModel = odataEdmModelReader.ReadMetadataDocument(settings);

If I set the IgnoreUnexpectedJsonElements property to false, I get the following exception:

Microsoft.OData.ODataException: The metadata document could not be read from the message content. UnexpectedElement : A member '$.Flows.Flows.Flows0.$Kind' with value type 'String' is unexpected. : $.Flows.Flows.Flows0.$Kind UnexpectedElement : A member '$.Flows.@sap.isPartial' with value type 'False' is unexpected. : $.Flows.@sap.isPartial

Expected result

These annotations shouldn't be considered as invalid elements, but stored as annotations so we can retrieve them in the IEdmModel.

Actual result

These annotations are not found in the IEdmModel but instead generate errors in the model.

habbes commented 3 months ago

The error involving the top-level annotation appears to be a bug. I got a similar error trying to parse one of the sample schemas in the CSDL JSON spec.

The other error related to the Flows0.$Kind entity set does not appear to be a bug, but rather an error in your schema. Here's the correct way to represent an entity set

"Flow0": {
-    "$Kind": "EntitySet",
+    "$Collection": true,
     "$Type": "Flows.Flow0"
}
xuzhg commented 3 months ago

https://github.com/OData/odata.net/blob/main/src/Microsoft.OData.Edm/Csdl/Parsing/SchemaJsonParser.cs#L72-L73

xuzhg commented 3 months ago

https://github.com/OData/odata.net/blob/main/src/Microsoft.OData.Edm/Csdl/CsdlJsonReaderSettings.cs#L26