diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyGetOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyGetOperationHandler.cs
index 9d025678..a24ed075 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyGetOperationHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyGetOperationHandler.cs
@@ -178,11 +178,12 @@ protected override void SetParameters(OpenApiOperation operation)
AddParameterIfExists(parametersToAdd, Context.CreateFilter, Context.CreateFilter);
AddParameterIfExists(parametersToAdd, Context.CreateCount, Context.CreateCount);
- var orderByParameter = (string.IsNullOrEmpty(TargetPath), NavigationProperty) switch
+ // Fall back only for unresolved targets, not for explicit sorting restrictions.
+ var orderByParameter = (string.IsNullOrEmpty(TargetPath) ? null : Context.Model.GetTargetPath(TargetPath), NavigationProperty) switch
{
- (false, not null) when NavigationProperty.ToEntityType() is {} entityType =>
- Context.CreateOrderBy(TargetPath!, entityType),
- (true, not null) => Context.CreateOrderBy(NavigationProperty),
+ ({} target, not null) when NavigationProperty.ToEntityType() is {} entityType =>
+ Context.CreateOrderBy(target, entityType),
+ (null, not null) => Context.CreateOrderBy(NavigationProperty),
_ => null,
};
if (orderByParameter != null)
diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/NavigationPropertyGetOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/NavigationPropertyGetOperationHandlerTests.cs
index 318287fd..6e3ad291 100644
--- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/NavigationPropertyGetOperationHandlerTests.cs
+++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/NavigationPropertyGetOperationHandlerTests.cs
@@ -6,7 +6,9 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
+using System.Xml.Linq;
using Microsoft.OData.Edm;
+using Microsoft.OData.Edm.Csdl;
using Microsoft.OpenApi.OData.Edm;
using Microsoft.OpenApi.OData.Generator;
using Microsoft.OpenApi.OData.PathItem.Tests;
@@ -145,6 +147,102 @@ public void CreateNavigationGetOperationViaComposableFunctionReturnsCorrectOpera
Assert.Contains(operation.Parameters, x => x.Name == "path");
}
+ [Theory]
+ [InlineData(true)]
+ [InlineData(false)]
+ public void CreateNavigationGetOperationWithUnresolvedFunctionTargetUsesPropertySortRestrictions(bool sortable)
+ {
+ VerifyNavigationSortRestrictions(viaFunction: true, propertySortable: sortable, pathSortable: null);
+ }
+
+ [Theory]
+ [InlineData(true, null)]
+ [InlineData(true, false)]
+ [InlineData(false, true)]
+ public void CreateNavigationGetOperationWithResolvedTargetUsesPathSortRestrictions(bool propertySortable, bool? pathSortable)
+ {
+ VerifyNavigationSortRestrictions(viaFunction: false, propertySortable, pathSortable);
+ }
+
+ private void VerifyNavigationSortRestrictions(bool viaFunction, bool propertySortable, bool? pathSortable)
+ {
+ string pathAnnotation = pathSortable.HasValue ? $@"
+
+
+
+
+
+
+ " : "";
+ string csdl = $@"
+
+
+
+
+
+
+
+
+
+
+
+ id
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {pathAnnotation}
+
+
+ ";
+ IEdmModel model = CsdlReader.Parse(XElement.Parse(csdl).CreateReader());
+ IEdmEntitySet tables = model.EntityContainer.FindEntitySet("tables");
+ IEdmNavigationProperty columns = tables.EntityType.DeclaredNavigationProperties().Single();
+ var path = new ODataPath(new ODataNavigationSourceSegment(tables));
+ if (viaFunction)
+ {
+ path.Push(new ODataOperationSegment(model.SchemaElements.OfType().Single()));
+ }
+ else
+ {
+ path.Push(new ODataKeySegment(tables.EntityType));
+ }
+ path.Push(new ODataNavigationPropertySegment(columns));
+
+ var target = model.GetTargetPath(path.GetTargetPath(model));
+ Assert.Equal(viaFunction, target is null);
+
+ var settings = new OpenApiConvertSettings { UseStringArrayForQueryOptionsSchema = false };
+ var operation = _operationHandler.CreateOperation(new ODataContext(model, settings), path);
+
+ if (viaFunction ? propertySortable : pathSortable ?? true)
+ {
+ var orderBy = Assert.Single(operation.Parameters, parameter => parameter.Name == "$orderby");
+ var expectedProperties = viaFunction
+ ? new[] { "name", "name desc" }
+ : new[] { "id", "id desc", "name", "name desc" };
+ Assert.Equal(expectedProperties, orderBy.Schema.Items.Enum.Select(value => value.GetValue()));
+ }
+ else
+ {
+ Assert.DoesNotContain(operation.Parameters, parameter => parameter.Name == "$orderby");
+ }
+ }
+
[Fact]
public void CreateNavigationGetOperationViaOverloadedComposableFunctionReturnsCorrectOperation()
{