Skip to content

Commit

Permalink
Fix for OData#592
Browse files Browse the repository at this point in the history
Description of problem:
Suppose there is a function getCurrentCustomer() whose EntitySetPath is not defined, if the request URL is /getCurrentCustomer()/oneNavigationProperty, the ODataPathParser.Parse() will throw NullReferenceException as the current code requires EntitySetPath to be specified on Function that returns an enitty type.

Description of fix:
As the EdmNavigationSource is not required for NavigationPropertySegment, we do not need to require the TargetEdmNavigationSource.
  • Loading branch information
shaofengzhu authored and LaylaLiu committed Jun 12, 2016
1 parent 975280f commit decf4fd
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1162,6 +1162,7 @@ private bool TryCreateTypeNameSegment(ODataPathSegment previous, string identifi
[SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "IEdmModel", Justification = "The spelling is correct.")]
private void CreatePropertySegment(ODataPathSegment previous, IEdmProperty property, string queryPortion)
{
Debug.Assert(previous != null, "previous != null");
if (property.Type.IsStream())
{
// The server used to allow arbitrary key expressions after named streams because this check was missing.
Expand All @@ -1180,7 +1181,11 @@ private void CreatePropertySegment(ODataPathSegment previous, IEdmProperty prope
if (property.PropertyKind == EdmPropertyKind.Navigation)
{
var navigationProperty = (IEdmNavigationProperty)property;
IEdmNavigationSource navigationSource = previous.TargetEdmNavigationSource.FindNavigationTarget(navigationProperty);
IEdmNavigationSource navigationSource = null;
if (previous.TargetEdmNavigationSource != null)
{
navigationSource = previous.TargetEdmNavigationSource.FindNavigationTarget(navigationProperty);
}

// Relationship between TargetMultiplicity and navigation property:
// 1) EdmMultiplicity.Many <=> collection navigation property
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ internal void AssertValid()
Debug.Assert(Enum.IsDefined(typeof(RequestTargetKind), this.TargetKind), "enum value is not valid");
Debug.Assert(
this.TargetKind != RequestTargetKind.Resource ||
this.TargetEdmNavigationSource != null ||
this.TargetEdmNavigationSource != null ||
this.TargetEdmType != null ||
this.TargetKind == RequestTargetKind.OpenProperty ||
this is OperationSegment ||
this is OperationImportSegment,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -512,5 +512,56 @@ public void ParseCompositeKeyReference(TestUrlConvention testUrlConvention, stri
}

#endregion

#region Null EntitySetPath

[Fact]
public void ParsePathFunctionWithNullEntitySetPath()
{
var model = new EdmModel();

var customer = new EdmEntityType("Test", "Customer", null, false, false);
var customerId = customer.AddStructuralProperty("id", EdmPrimitiveTypeKind.String, false);
customer.AddKeys(customerId);
model.AddElement(customer);

var detail = new EdmEntityType("Test", "Detail", null, false, true);
detail.AddStructuralProperty("address", EdmPrimitiveTypeKind.String, true);
model.AddElement(detail);

var customerDetail = customer.AddUnidirectionalNavigation(
new EdmNavigationPropertyInfo()
{
Name = "detail",
Target = detail,
TargetMultiplicity = EdmMultiplicity.One,
ContainsTarget = true
});

// The test is to make sure the ODataUriParser works even though
// the entitySetPathExpression is null.
var getCurrentCustomer = new EdmFunction(
"Test",
"getCurrentCustomer",
new EdmEntityTypeReference(customer, false),
isBound: false,
entitySetPathExpression: null,
isComposable: true);
model.AddElement(getCurrentCustomer);

var container = new EdmEntityContainer("Test", "Container");
var getCurrentCustomerImport = container.AddFunctionImport(getCurrentCustomer);
model.AddElement(container);

var parser = new ODataUriParser(model, new Uri("http://host"), new Uri("http://host/getCurrentCustomer()/detail"));
var path = parser.ParsePath();
var pathSegmentList = path.ToList();
pathSegmentList.Count.Should().Be(2);
pathSegmentList[0].ShouldBeOperationImportSegment(getCurrentCustomerImport);
pathSegmentList[1].ShouldBeNavigationPropertySegment(customerDetail);
}

#endregion

}
}

0 comments on commit decf4fd

Please sign in to comment.