odata.net
odata.net copied to clipboard
Potential regression causes exception when calling $select against stream type
Let's assume we have URL where the last segment is a stream property, and it has a $select query option:
/People(1)/StreamProp?$select=...
Then we parse this url with parser.ParseUri()
or parser.ParseSelectAndExpand
.
In 7.10.0, this parse works successfully
In 7.11.0 the parse fails with the following exception message:
The type 'Edm.Stream' is not valid for $select or $expand, only structured types are allowed. ---> Microsoft.OData.ODataException: The type 'Edm.Stream' is not valid for $select or $expand, only structured types are allowed.
According the spec, expanding a stream property is allowed: https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_SystemQueryOptionexpand
But that seems to refer to when the property is part of the expand path: $expand=StreamProperty
. Not sure if it also applies when the stream property is the last segment of the resource URL.
I'm not sure this is actually a bug. But this has caused a test case to fail when migrating AGS from ODL 7.10.0
Assemblies affected
Microsoft.OData.Core 7.11.0 and later
Reproduce steps
Create a model with an entity type that has a stream property (in this case Assignment
):
var model = new EdmModel();
var classType = model.AddEntityType("Models", "Class");
var assignmentType = model.AddEntityType("Models", "Assignment");
var classId = classType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.String);
classType.AddKeys(classId);
var assgnId = assignmentType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.String);
assignmentType.AddKeys(assgnId);
assignmentType.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);
assignmentType.AddStructuralProperty("StreamProp", EdmPrimitiveTypeKind.Stream);
classType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo()
{
Name = "Assignments",
Target = assignmentType,
TargetMultiplicity = EdmMultiplicity.Many,
ContainsTarget = false
});
var container = model.AddEntityContainer("Models", "Container");
container.AddEntitySet("classes", classType);
container.AddEntitySet("assignments", assignmentType);
Parse a URL where the stream property is the last segment, and there's a $select
option (the value of the select doesn't happen):
var parser = new ODataUriParser(model, new Uri("classes('id')/Assignments('id')/StreamProp?$select=StreamProp", UriKind.Relative));
ODataUri path = parser.ParseUri();
Expected result
It should not throw an exception.
Actual result
It throws an ODataException
Additional detail
The exception is thrown in the ODataUriQueryOptionParser.ParseSelectAndExpand
method. When running the scenario above in 7.10.0, this.targetEdmType
evaluates to Assignment
, but in 7.11.0 it evaluates to Edm.Stream
.