Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Contained Navigation Property on Derived Type Serialization Fails in Full MetaData #2774

Closed
EvanHennisAtMicrosoft opened this issue Oct 18, 2023 · 4 comments · Fixed by #2775

Comments

@EvanHennisAtMicrosoft
Copy link

Short summary (3-5 sentences) describing the issue.

When we have a base type (accountsWithAccess) with a derived type (enumeratedAccountsWithAccess) with a Navigation property on it (accounts) our code breaks when we try and write the full metadata
base type -> derived type -> navigation property

The "Identifier" on the TypeSegment is null.

Schema:





Stack Trace:
System.ArgumentNullException: Value cannot be null or empty. (Parameter 'entitySetName')
at Microsoft.OData.ExceptionUtils.CheckArgumentStringNotNullOrEmpty(String value, String parameterName)
at Microsoft.OData.Evaluation.ODataConventionalUriBuilder.BuildEntitySetUri(Uri baseUri, String entitySetName)
at Microsoft.OData.Evaluation.ODataConventionalIdMetadataBuilder.GetContainingEntitySetUri(Uri baseUri, ODataPath path)
at Microsoft.OData.Evaluation.ODataConventionalIdMetadataBuilder.ComputeIdForContainment()
at Microsoft.OData.Evaluation.ODataConventionalIdMetadataBuilder.ComputeAndCacheId()
at Microsoft.OData.Evaluation.ODataConventionalIdMetadataBuilder.get_ComputedId()
at Microsoft.OData.Evaluation.ODataConventionalIdMetadataBuilder.GetId()
at Microsoft.OData.Evaluation.ODataConventionalEntityMetadataBuilder.TryGetIdForSerialization(Uri& id)
at Microsoft.OData.JsonLight.ODataJsonLightResourceSerializer.WriteResourceStartMetadataPropertiesAsync(IODataJsonLightWriterResourceState resourceState)
at Microsoft.OData.JsonLight.ODataJsonLightWriter.StartResourceAsync(ODataResource resource)
at Microsoft.OData.ODataWriterCore.<>c.<b__196_0>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.OData.ODataWriterCore.InterceptExceptionAsync[TArg0](Func`3 action, TArg0 arg0)
at Microsoft.OData.ODataWriterCore.WriteStartResourceImplementationAsync(ODataResource resource)
at Microsoft.AspNetCore.OData.Formatter.Serialization.ODataResourceSerializer.WriteResourceAsync(Object graph, ODataWriter writer, ODataSerializerContext writeContext, IEdmTypeReference expectedType)
at Microsoft.AspNetCore.OData.Formatter.Serialization.ODataResourceSerializer.WriteObjectInlineAsync(Object graph, IEdmTypeReference expectedType, ODataWriter writer, ODataSerializerContext writeContext)
at Microsoft.AspNetCore.OData.Formatter.Serialization.ODataResourceSetSerializer.WriteResourceSetAsync(IEnumerable enumerable, IEdmTypeReference resourceSetType, ODataWriter writer, ODataSerializerContext writeContext)
at Microsoft.AspNetCore.OData.Formatter.Serialization.ODataResourceSetSerializer.WriteObjectInlineAsync(Object graph, IEdmTypeReference expectedType, ODataWriter writer, ODataSerializerContext writeContext)
at Microsoft.AspNetCore.OData.Formatter.Serialization.ODataResourceSerializer.WriteComplexAndExpandedNavigationPropertyAsync(IEdmProperty edmProperty, SelectItem selectItem, ResourceContext resourceContext, ODataWriter writer)
at Microsoft.AspNetCore.OData.Formatter.Serialization.ODataResourceSerializer.WriteExpandedNavigationPropertiesAsync(SelectExpandNode selectExpandNode, ResourceContext resourceContext, ODataWriter writer)
at Microsoft.AspNetCore.OData.Formatter.Serialization.ODataResourceSerializer.WriteResourceAsync(Object graph, ODataWriter writer, ODataSerializerContext writeContext, IEdmTypeReference expectedType)
at Microsoft.AspNetCore.OData.Formatter.Serialization.ODataResourceSerializer.WriteObjectInlineAsync(Object graph, IEdmTypeReference expectedType, ODataWriter writer, ODataSerializerContext writeContext)
at Microsoft.AspNetCore.OData.Formatter.Serialization.ODataResourceSerializer.WriteObjectAsync(Object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)
at Microsoft.AspNetCore.OData.Formatter.ODataOutputFormatterHelper.WriteToStreamAsync(Type type, Object value, IEdmModel model, ODataVersion version, Uri baseAddress, MediaTypeHeaderValue contentType, HttpRequest request, IHeaderDictionary requestHeaders, IODataSerializerProvider serializerProvider)

Assemblies affected

Which assemblies and versions are known to be affected e.g. OData .Net lib 7.x
Microsoft.AspNetCore.OData.dll v8.02.0.40518
Microsoft.OData.Edm.dll v7.16.0.40516
Microsoft.OData.Core.dll v7.16.0.40516
Microsoft.OData.ModelBuilder.dll v1.00.9.30610

Reproduce steps

The simplest set of steps to reproduce the issue. If possible, reference a commit that demonstrates the issue.
There is a lot of proprietary information with our code but adding Accept: application/json;odata.metadata=full breaks.

Expected result

What would happen if there wasn't a bug.
We should have the odata type written out for all the types. Oddly enough, when we call it WITHOUT the metadata=full we do see the types of the child navigation type.

Actual result

What is actually happening.
Throws an exception and won't print the results.

Additional detail

Optional, details of the root cause if known. Delete this section if you have no additional details to add.

@EvanHennisAtMicrosoft
Copy link
Author

Here is a screengrab of the GetContainingEntitySetUri method. By default, the TypeSegment does NOT fill in the Identifier property. I added that property to all of the segments that I build but it appears that when the last segment is a property segment a new TypeSegment is autogenerated by the library.

image

@EvanHennisAtMicrosoft
Copy link
Author

Here is an example of the extra TypeSegment that was added by OData.

image

xuzhg added a commit that referenced this issue Oct 19, 2023
Most of segments have set the identifier. But Some doesn't.
Identifier is used to generate Id, it cannot be 'null'.
@xuzhg
Copy link
Member

xuzhg commented Oct 19, 2023

I uploaded the repro.
WebApplication3.zip

The project is modified to use the project reference. So, Download the zip need some changes to build and run. you should:

  1. git clone 'https://github.com/OData/AspNetCoreOData'
  2. git clone 'https://github.com/OData/odata.net'
  3. Update the project reference in 'Microsoft.AspNetCore.OData.csproj" for "Microsoft.OData.Edm" and "Microsoft.OData.Core" and "Microsoft.Spatial"
  4. Update the project reference in WebApplication3.csproj for 'Microsoft.AspNetCore.OData".

Run it and send request: http://localhost:5197/odata/IdentityGovernance/PermissionsAnalytics/Findings/%7Bkey%7D/WebApplication3.Models.ExternallyFinding/AccountsWithAccess

Accept=application/json;odata.metadata=full

If you use the existing "Microsoft.OData.Core" codes, it will fail.

If you use the codes in the above PR, it will be successful as:

image

@EvanHennisAtMicrosoft
Copy link
Author

I downloaded the source posted and recreated the failure. I changed the branch on odata.net to issue2774 and the issue was fixed.

xuzhg added a commit that referenced this issue Oct 26, 2023
* Fixes #2774: set the identifier for segments
Most of segments have set the identifier. But Some doesn't.
Identifier is used to generate Id, it cannot be 'null'.

* Update src/Microsoft.OData.Core/UriParser/SemanticAst/KeySegment.cs

Co-authored-by: John Gathogo <john.gathogo@microsoft.com>

---------

Co-authored-by: John Gathogo <john.gathogo@microsoft.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants