diff --git a/src/Microsoft.OData.Core/ODataContextUrlInfo.cs b/src/Microsoft.OData.Core/ODataContextUrlInfo.cs
index 6ec3b7170c..86cc7b85cc 100644
--- a/src/Microsoft.OData.Core/ODataContextUrlInfo.cs
+++ b/src/Microsoft.OData.Core/ODataContextUrlInfo.cs
@@ -297,7 +297,7 @@ private static string ComputeNavigationPath(EdmNavigationSourceKind kind, ODataU
string navigationPath = null;
if (kind == EdmNavigationSourceKind.ContainedEntitySet && odataUri != null && odataUri.Path != null)
{
- ODataPath odataPath = odataUri.Path.TrimEndingTypeSegment().TrimEndingKeySegment();
+ ODataPath odataPath = odataUri.Path.TrimEndingTypeAndKeySegments();
if (!(odataPath.LastSegment is NavigationPropertySegment) && !(odataPath.LastSegment is OperationSegment))
{
throw new ODataException(Strings.ODataContextUriBuilder_ODataPathInvalidForContainedElement(odataPath.ToContextUrlPathString()));
@@ -322,15 +322,13 @@ private static string ComputeNavigationPath(EdmNavigationSourceKind kind, in ODa
string navigationPath = null;
if (kind == EdmNavigationSourceKind.ContainedEntitySet && odataUri.Path != null)
{
- ODataPath odataPath = odataUri.Path.TrimEndingTypeSegment().TrimEndingKeySegment();
+ ODataPath odataPath = odataUri.Path.TrimEndingTypeAndKeySegments();
if (!(odataPath.LastSegment is NavigationPropertySegment) && !(odataPath.LastSegment is OperationSegment))
{
throw new ODataException(Strings.ODataContextUriBuilder_ODataPathInvalidForContainedElement(odataPath.ToContextUrlPathString()));
}
-
navigationPath = odataPath.ToContextUrlPathString();
}
-
return navigationPath ?? navigationSource;
}
diff --git a/src/Microsoft.OData.Core/PublicAPI/net45/PublicAPI.Unshipped.txt b/src/Microsoft.OData.Core/PublicAPI/net45/PublicAPI.Unshipped.txt
index e69de29bb2..103f295f00 100644
--- a/src/Microsoft.OData.Core/PublicAPI/net45/PublicAPI.Unshipped.txt
+++ b/src/Microsoft.OData.Core/PublicAPI/net45/PublicAPI.Unshipped.txt
@@ -0,0 +1 @@
+static Microsoft.OData.UriParser.ODataPathExtensions.TrimEndingTypeAndKeySegments(this Microsoft.OData.UriParser.ODataPath path) -> Microsoft.OData.UriParser.ODataPath
\ No newline at end of file
diff --git a/src/Microsoft.OData.Core/PublicAPI/netcoreapp3.1/PublicAPI.Unshipped.txt b/src/Microsoft.OData.Core/PublicAPI/netcoreapp3.1/PublicAPI.Unshipped.txt
index e69de29bb2..103f295f00 100644
--- a/src/Microsoft.OData.Core/PublicAPI/netcoreapp3.1/PublicAPI.Unshipped.txt
+++ b/src/Microsoft.OData.Core/PublicAPI/netcoreapp3.1/PublicAPI.Unshipped.txt
@@ -0,0 +1 @@
+static Microsoft.OData.UriParser.ODataPathExtensions.TrimEndingTypeAndKeySegments(this Microsoft.OData.UriParser.ODataPath path) -> Microsoft.OData.UriParser.ODataPath
\ No newline at end of file
diff --git a/src/Microsoft.OData.Core/PublicAPI/netstandard1.1/PublicAPI.Unshipped.txt b/src/Microsoft.OData.Core/PublicAPI/netstandard1.1/PublicAPI.Unshipped.txt
index e69de29bb2..103f295f00 100644
--- a/src/Microsoft.OData.Core/PublicAPI/netstandard1.1/PublicAPI.Unshipped.txt
+++ b/src/Microsoft.OData.Core/PublicAPI/netstandard1.1/PublicAPI.Unshipped.txt
@@ -0,0 +1 @@
+static Microsoft.OData.UriParser.ODataPathExtensions.TrimEndingTypeAndKeySegments(this Microsoft.OData.UriParser.ODataPath path) -> Microsoft.OData.UriParser.ODataPath
\ No newline at end of file
diff --git a/src/Microsoft.OData.Core/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt b/src/Microsoft.OData.Core/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt
index e69de29bb2..103f295f00 100644
--- a/src/Microsoft.OData.Core/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt
+++ b/src/Microsoft.OData.Core/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt
@@ -0,0 +1 @@
+static Microsoft.OData.UriParser.ODataPathExtensions.TrimEndingTypeAndKeySegments(this Microsoft.OData.UriParser.ODataPath path) -> Microsoft.OData.UriParser.ODataPath
\ No newline at end of file
diff --git a/src/Microsoft.OData.Core/UriParser/SemanticAst/ODataPathExtensions.cs b/src/Microsoft.OData.Core/UriParser/SemanticAst/ODataPathExtensions.cs
index 87b4fa1bbc..f0d02cd1c5 100644
--- a/src/Microsoft.OData.Core/UriParser/SemanticAst/ODataPathExtensions.cs
+++ b/src/Microsoft.OData.Core/UriParser/SemanticAst/ODataPathExtensions.cs
@@ -137,6 +137,22 @@ public static ODataPath TrimEndingTypeSegment(this ODataPath path)
return handler.FirstPart;
}
+ ///
+ /// Creates a that is with the type segments and key segments removed from the end
+ ///
+ /// The to trim the ending of
+ /// A without type-cast and key segments at the end
+ /// Thrown if is
+ public static ODataPath TrimEndingTypeAndKeySegments(this ODataPath path)
+ {
+ if (path == null)
+ {
+ throw Error.ArgumentNull(nameof(path));
+ }
+
+ return new ODataPath(path.Segments.Take(path.Segments.FindLastIndex(segment => !(segment is KeySegment || segment is TypeSegment)) + 1));
+ }
+
///
/// Creates a new ODataPath with the specified segment added.
///
diff --git a/src/Microsoft.OData.Edm/PublicAPI/net45/PublicAPI.Unshipped.txt b/src/Microsoft.OData.Edm/PublicAPI/net45/PublicAPI.Unshipped.txt
index 5f282702bb..9271da2b65 100644
--- a/src/Microsoft.OData.Edm/PublicAPI/net45/PublicAPI.Unshipped.txt
+++ b/src/Microsoft.OData.Edm/PublicAPI/net45/PublicAPI.Unshipped.txt
@@ -1 +1,2 @@
-
\ No newline at end of file
+static System.Collections.Generic.ReadOnlyListExtensions.FindLastIndex(this System.Collections.Generic.IReadOnlyList list, System.Func predicate) -> int
+System.Collections.Generic.ReadOnlyListExtensions
\ No newline at end of file
diff --git a/src/Microsoft.OData.Edm/PublicAPI/netstandard1.1/PublicAPI.Unshipped.txt b/src/Microsoft.OData.Edm/PublicAPI/netstandard1.1/PublicAPI.Unshipped.txt
index 5f282702bb..9271da2b65 100644
--- a/src/Microsoft.OData.Edm/PublicAPI/netstandard1.1/PublicAPI.Unshipped.txt
+++ b/src/Microsoft.OData.Edm/PublicAPI/netstandard1.1/PublicAPI.Unshipped.txt
@@ -1 +1,2 @@
-
\ No newline at end of file
+static System.Collections.Generic.ReadOnlyListExtensions.FindLastIndex(this System.Collections.Generic.IReadOnlyList list, System.Func predicate) -> int
+System.Collections.Generic.ReadOnlyListExtensions
\ No newline at end of file
diff --git a/src/Microsoft.OData.Edm/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt b/src/Microsoft.OData.Edm/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt
index 5f282702bb..9271da2b65 100644
--- a/src/Microsoft.OData.Edm/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt
+++ b/src/Microsoft.OData.Edm/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt
@@ -1 +1,2 @@
-
\ No newline at end of file
+static System.Collections.Generic.ReadOnlyListExtensions.FindLastIndex(this System.Collections.Generic.IReadOnlyList list, System.Func predicate) -> int
+System.Collections.Generic.ReadOnlyListExtensions
\ No newline at end of file
diff --git a/src/Microsoft.OData.Edm/System/Collections/Generic/ReadOnlyListExtensions.cs b/src/Microsoft.OData.Edm/System/Collections/Generic/ReadOnlyListExtensions.cs
new file mode 100644
index 0000000000..c1aafd4aeb
--- /dev/null
+++ b/src/Microsoft.OData.Edm/System/Collections/Generic/ReadOnlyListExtensions.cs
@@ -0,0 +1,45 @@
+namespace System.Collections.Generic
+{
+ ///
+ /// Extensions methods
+ ///
+ public static class ReadOnlyListExtensions
+ {
+ ///
+ /// Searches for an element that matches the conditions defined by the specified predicate, and returns the zero-based index of the last occurrence within the
+ /// entire
+ ///
+ /// The type of the elements in
+ /// The to find the index of the last element of
+ /// The delegate that defines the conditions of the element to search for.
+ ///
+ /// The zero-based index of the last occurrence of an element that matches the conditions defined by , if found; otherwise, -1
+ ///
+ /// Thrown if or is
+ ///
+ /// Copied from
+ ///
+ public static int FindLastIndex(this IReadOnlyList list, Func predicate)
+ {
+ if (list == null)
+ {
+ throw new ArgumentNullException(nameof(list));
+ }
+
+ if (predicate == null)
+ {
+ throw new ArgumentNullException(nameof(predicate));
+ }
+
+ for (int i = list.Count - 1; i > -1; --i)
+ {
+ if (predicate(list[i]))
+ {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+ }
+}
diff --git a/test/FunctionalTests/Microsoft.OData.Core.Tests/JsonLight/GenerateContextUrlFromSlimUriWithDerivedTypeCastAndKeySegment.xml b/test/FunctionalTests/Microsoft.OData.Core.Tests/JsonLight/GenerateContextUrlFromSlimUriWithDerivedTypeCastAndKeySegment.xml
new file mode 100644
index 0000000000..94745422cd
--- /dev/null
+++ b/test/FunctionalTests/Microsoft.OData.Core.Tests/JsonLight/GenerateContextUrlFromSlimUriWithDerivedTypeCastAndKeySegment.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/FunctionalTests/Microsoft.OData.Core.Tests/JsonLight/ODataJsonLightWriterTests.cs b/test/FunctionalTests/Microsoft.OData.Core.Tests/JsonLight/ODataJsonLightWriterTests.cs
index d07e797efd..9dc9ccc998 100644
--- a/test/FunctionalTests/Microsoft.OData.Core.Tests/JsonLight/ODataJsonLightWriterTests.cs
+++ b/test/FunctionalTests/Microsoft.OData.Core.Tests/JsonLight/ODataJsonLightWriterTests.cs
@@ -8,11 +8,18 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
+using System.Linq;
+using System.Reflection;
using System.Text;
using System.Threading.Tasks;
+using System.Xml;
using Microsoft.OData.Edm;
+using Microsoft.OData.Edm.Csdl;
+#if NETCOREAPP3_1_OR_GREATER
using Microsoft.OData.Json;
+#endif
using Microsoft.OData.JsonLight;
+using Microsoft.OData.UriParser;
using Microsoft.OData.Tests;
using Microsoft.Test.OData.DependencyInjection;
using Xunit;
@@ -739,6 +746,181 @@ public async Task WriteEntityReferenceLinkAsync()
result);
}
+ ///
+ /// Gets the name of the caller method of this method
+ ///
+ /// The string that the method name of the caller will be written into
+ /// The name of the caller method of this method
+ public static string GetCurrentMethodName([System.Runtime.CompilerServices.CallerMemberName] string caller = null)
+ {
+ return caller;
+ }
+
+ ///
+ /// A that pretends to be the "products" contained navigation collection for the purposes of computing a context URL
+ ///
+ private sealed class MockNavigationSource : IEdmNavigationSource, IEdmContainedEntitySet, IEdmUnknownEntitySet
+ {
+ public IEnumerable NavigationPropertyBindings => throw new NotImplementedException();
+
+ public IEdmPathExpression Path => throw new NotImplementedException();
+
+ public IEdmType Type => new EdmEntityType("ns", "products");
+
+ public string Name => "products";
+
+ public IEdmNavigationSource ParentNavigationSource => throw new NotImplementedException();
+
+ public IEdmNavigationProperty NavigationProperty => throw new NotImplementedException();
+
+ public IEnumerable FindNavigationPropertyBindings(IEdmNavigationProperty navigationProperty)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IEdmNavigationSource FindNavigationTarget(IEdmNavigationProperty navigationProperty)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IEdmNavigationSource FindNavigationTarget(IEdmNavigationProperty navigationProperty, IEdmPathExpression bindingPath)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+#if !NETCOREAPP1_1
+ ///
+ /// Generates a context URL from a that ends with cast and key segments
+ ///
+ ///
+ [Fact]
+ public static void GenerateContextUrlFromSlimUriWithDerivedTypeCastAndKeySegment()
+ {
+ var domain = new Uri("http://tempuri.org");
+ var requestUrl = new Uri(domain, "/orders('1')/products/ns.derivedProduct('2')");
+
+ // load the CSDL from the embedded resources
+ var assembly = Assembly.GetExecutingAssembly();
+ var currentMethod = GetCurrentMethodName();
+ var csdlResourceName = assembly.GetManifestResourceNames().Where(name => name.EndsWith($"{currentMethod}.xml")).Single();
+
+ // parse the CSDL
+ IEdmModel model;
+ using (var csdlResourceStream = assembly.GetManifestResourceStream(csdlResourceName))
+ {
+ using (var xmlReader = XmlReader.Create(csdlResourceStream))
+ {
+ if (!CsdlReader.TryParse(xmlReader, out model, out var errors))
+ {
+ Assert.True(false, string.Join(Environment.NewLine, errors));
+ }
+ }
+ }
+
+ var uriParser = new ODataUriParser(model, domain, requestUrl);
+ var slimUri = new ODataUriSlim(uriParser.ParseUri());
+ var contextUrlInfo = ODataContextUrlInfo.Create(new MockNavigationSource(), "ns.product", true, slimUri, ODataVersion.V4);
+ Assert.Equal(@"orders('1')/products", contextUrlInfo.NavigationPath);
+ }
+
+ ///
+ /// Writes a resource as the response to a request where the URL ends with a combined cast and key segment
+ ///
+ ///
+ [Fact]
+ public static async Task WriteContextWithDerivedTypeCastAndKeySegmentAsync()
+ {
+ var domain = new Uri("http://tempuri.org");
+ var requestUrl = new Uri(domain, "/orders('1')/products/ns.derivedProduct('2')");
+ var serviceSideResponseResource = new ODataResource
+ {
+ TypeName = "ns.product",
+ Properties = new List
+ {
+ new ODataProperty
+ {
+ Name = "id",
+ Value = "1",
+ SerializationInfo = new ODataPropertySerializationInfo
+ {
+ PropertyKind = ODataPropertyKind.Key
+ },
+ },
+ new ODataProperty
+ {
+ Name = "name",
+ Value = "somename",
+ },
+ },
+ };
+ var expectedResponsePayload =
+ "{" +
+ "\"@odata.context\":\"http://tempuri.org/$metadata#orders('1')/products/$entity\"," +
+ "\"id\":\"1\"," +
+ "\"name\":\"somename\"" +
+ "}";
+
+ // load the CSDL from the embedded resources
+ var assembly = Assembly.GetExecutingAssembly();
+ var currentMethod = GetCurrentMethodName();
+ var csdlResourceName = assembly.GetManifestResourceNames().Where(name => name.EndsWith($"{currentMethod}.xml")).Single();
+
+ // parse the CSDL
+ IEdmModel model;
+ using (var csdlResourceStream = assembly.GetManifestResourceStream(csdlResourceName))
+ {
+ using (var xmlReader = XmlReader.Create(csdlResourceStream))
+ {
+ if (!CsdlReader.TryParse(xmlReader, out model, out var errors))
+ {
+ Assert.True(false, string.Join(Environment.NewLine, errors));
+ }
+ }
+ }
+
+ using (var memoryStream = new MemoryStream())
+ {
+ // initialize the json response writer
+ var uriParser = new ODataUriParser(model, domain, requestUrl);
+ var odataMessageWriterSettings = new ODataMessageWriterSettings
+ {
+ EnableMessageStreamDisposal = false,
+ Version = ODataVersion.V4,
+ ShouldIncludeAnnotation = ODataUtils.CreateAnnotationFilter("*"),
+ ODataUri = uriParser.ParseUri(),
+ };
+ var messageInfo = new ODataMessageInfo
+ {
+ MessageStream = memoryStream,
+ MediaType = new ODataMediaType("application", "json"),
+ Encoding = Encoding.Default,
+ IsResponse = true,
+ IsAsync = true,
+ Model = model,
+ };
+ var jsonLightOutputContext = new ODataJsonLightOutputContext(messageInfo, odataMessageWriterSettings);
+ var jsonLightWriter = new ODataJsonLightWriter(
+ jsonLightOutputContext,
+ null,
+ null,
+ false);
+
+ // write the response
+ await jsonLightWriter.WriteStartAsync(serviceSideResponseResource);
+ await jsonLightWriter.WriteEndAsync();
+
+ // confirm that the written response was the expected response
+ memoryStream.Position = 0;
+ using (var streamReader = new StreamReader(memoryStream))
+ {
+ var actualResponsePayload = await streamReader.ReadToEndAsync();
+ Assert.Equal(expectedResponsePayload, actualResponsePayload);
+ }
+ }
+ }
+#endif
+
[Fact]
public async Task WriteEntityReferenceLinkForCollectionNavigationPropertyAsync()
{
diff --git a/test/FunctionalTests/Microsoft.OData.Core.Tests/JsonLight/WriteContextWithDerivedTypeCastAndKeySegmentAsync.xml b/test/FunctionalTests/Microsoft.OData.Core.Tests/JsonLight/WriteContextWithDerivedTypeCastAndKeySegmentAsync.xml
new file mode 100644
index 0000000000..62f8053d86
--- /dev/null
+++ b/test/FunctionalTests/Microsoft.OData.Core.Tests/JsonLight/WriteContextWithDerivedTypeCastAndKeySegmentAsync.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/FunctionalTests/Microsoft.OData.Core.Tests/Microsoft.OData.Core.Tests.csproj b/test/FunctionalTests/Microsoft.OData.Core.Tests/Microsoft.OData.Core.Tests.csproj
index 3935c6030e..abe5dc87d9 100644
--- a/test/FunctionalTests/Microsoft.OData.Core.Tests/Microsoft.OData.Core.Tests.csproj
+++ b/test/FunctionalTests/Microsoft.OData.Core.Tests/Microsoft.OData.Core.Tests.csproj
@@ -51,6 +51,11 @@
+
+
+
+
+
@@ -61,6 +66,11 @@
+
+
+
+
+
diff --git a/test/FunctionalTests/Microsoft.OData.Core.Tests/UriParser/SemanticAst/ODataPathExtensionsTests.cs b/test/FunctionalTests/Microsoft.OData.Core.Tests/UriParser/SemanticAst/ODataPathExtensionsTests.cs
index 23d9f8aa68..4883294325 100644
--- a/test/FunctionalTests/Microsoft.OData.Core.Tests/UriParser/SemanticAst/ODataPathExtensionsTests.cs
+++ b/test/FunctionalTests/Microsoft.OData.Core.Tests/UriParser/SemanticAst/ODataPathExtensionsTests.cs
@@ -251,6 +251,53 @@ public void TestTrimEndingTypeCast()
}
}
+ ///
+ /// Test trimming the end of a path of it's key and type segments
+ ///
+ [Fact]
+ public void TrimEndingTypeAndKeySegments()
+ {
+ var testCases = new[]
+ {
+ new {
+ Url = "People",
+ Trimmed = "People"
+ },
+ new {
+ Url = "People(1)",
+ Trimmed = "People"
+ },
+ new {
+ Url = "People/Fully.Qualified.Namespace.Employee",
+ Trimmed = "People"
+ },
+ new {
+ Url = "People(1)/Fully.Qualified.Namespace.Employee",
+ Trimmed = "People"
+ },
+ new {
+ Url = "People/Fully.Qualified.Namespace.Employee/1",
+ Trimmed = "People"
+ },
+ new {
+ Url = "People/Fully.Qualified.Namespace.Employee/1/MyAddress",
+ Trimmed = "People/Fully.Qualified.Namespace.Employee/1/MyAddress"
+ },
+ new {
+ Url = "People(1)/Fully.Qualified.Namespace.Employee/MyAddress",
+ Trimmed = "People/1/Fully.Qualified.Namespace.Employee/MyAddress"
+ },
+ };
+
+ foreach (var testCase in testCases)
+ {
+ ODataUriParser parser = new ODataUriParser(HardCodedTestModel.TestModel, this.testBaseUri, new Uri(this.testBaseUri, testCase.Url));
+ ODataPath path = parser.ParsePath();
+ var result = path.TrimEndingTypeAndKeySegments();
+ Assert.Equal(testCase.Trimmed, result.ToResourcePathString(ODataUrlKeyDelimiter.Slash));
+ }
+ }
+
[Fact]
public void TestIsIndividualProperty()
{
diff --git a/test/FunctionalTests/Microsoft.OData.Edm.Tests/System/Collections/Generic/ReadOnlyListExtensionsTests.cs b/test/FunctionalTests/Microsoft.OData.Edm.Tests/System/Collections/Generic/ReadOnlyListExtensionsTests.cs
new file mode 100644
index 0000000000..58b9e43d82
--- /dev/null
+++ b/test/FunctionalTests/Microsoft.OData.Edm.Tests/System/Collections/Generic/ReadOnlyListExtensionsTests.cs
@@ -0,0 +1,24 @@
+namespace System.Collections.Generic
+{
+ using Xunit;
+
+ ///
+ /// Extensions methods
+ ///
+ public sealed class ReadOnlyListExtensionsTests
+ {
+ ///
+ /// Copied from
+ ///
+ [Fact]
+ public void FindLastIndex()
+ {
+ var intArray = new int[] { 40, 41, 42, 43, 44, 45, 46, 47, 48, 49 };
+ Assert.Equal(9, intArray.FindLastIndex(i => i >= 43));
+ Assert.Equal(-1, intArray.FindLastIndex(i => i == 99));
+
+ intArray = new int[0];
+ Assert.Equal(-1, intArray.FindLastIndex(i => i == 43));
+ }
+ }
+}
diff --git a/test/PublicApiTests/BaseLine/Microsoft.OData.PublicApi.net45.bsl b/test/PublicApiTests/BaseLine/Microsoft.OData.PublicApi.net45.bsl
index f91c6bb217..f3062d6cec 100644
--- a/test/PublicApiTests/BaseLine/Microsoft.OData.PublicApi.net45.bsl
+++ b/test/PublicApiTests/BaseLine/Microsoft.OData.PublicApi.net45.bsl
@@ -2914,6 +2914,16 @@ public sealed class Microsoft.OData.Edm.EdmUntypedStructuredType : Microsoft.ODa
Microsoft.OData.Edm.EdmTypeKind TypeKind { public virtual get; }
}
+[
+ExtensionAttribute(),
+]
+public sealed class System.Collections.Generic.ReadOnlyListExtensions {
+ [
+ ExtensionAttribute(),
+ ]
+ public static int FindLastIndex (IReadOnlyList`1 list, Func`2 predicate)
+}
+
public enum Microsoft.OData.Edm.Csdl.CsdlTarget : int {
EntityFramework = 0
OData = 1
@@ -6408,6 +6418,11 @@ public sealed class Microsoft.OData.UriParser.ODataPathExtensions {
]
public static Microsoft.OData.UriParser.ODataPath TrimEndingKeySegment (Microsoft.OData.UriParser.ODataPath path)
+ [
+ ExtensionAttribute(),
+ ]
+ public static Microsoft.OData.UriParser.ODataPath TrimEndingTypeAndKeySegments (Microsoft.OData.UriParser.ODataPath path)
+
[
ExtensionAttribute(),
]
diff --git a/test/PublicApiTests/BaseLine/Microsoft.OData.PublicApi.netstandard1.1.bsl b/test/PublicApiTests/BaseLine/Microsoft.OData.PublicApi.netstandard1.1.bsl
index c30f3b01e8..787f26974f 100644
--- a/test/PublicApiTests/BaseLine/Microsoft.OData.PublicApi.netstandard1.1.bsl
+++ b/test/PublicApiTests/BaseLine/Microsoft.OData.PublicApi.netstandard1.1.bsl
@@ -2914,6 +2914,16 @@ public sealed class Microsoft.OData.Edm.EdmUntypedStructuredType : Microsoft.ODa
Microsoft.OData.Edm.EdmTypeKind TypeKind { public virtual get; }
}
+[
+ExtensionAttribute(),
+]
+public sealed class System.Collections.Generic.ReadOnlyListExtensions {
+ [
+ ExtensionAttribute(),
+ ]
+ public static int FindLastIndex (IReadOnlyList`1 list, Func`2 predicate)
+}
+
public enum Microsoft.OData.Edm.Csdl.CsdlTarget : int {
EntityFramework = 0
OData = 1
@@ -6408,6 +6418,11 @@ public sealed class Microsoft.OData.UriParser.ODataPathExtensions {
]
public static Microsoft.OData.UriParser.ODataPath TrimEndingKeySegment (Microsoft.OData.UriParser.ODataPath path)
+ [
+ ExtensionAttribute(),
+ ]
+ public static Microsoft.OData.UriParser.ODataPath TrimEndingTypeAndKeySegments (Microsoft.OData.UriParser.ODataPath path)
+
[
ExtensionAttribute(),
]
diff --git a/test/PublicApiTests/BaseLine/Microsoft.OData.PublicApi.netstandard2.0.bsl b/test/PublicApiTests/BaseLine/Microsoft.OData.PublicApi.netstandard2.0.bsl
index f91c6bb217..f3062d6cec 100644
--- a/test/PublicApiTests/BaseLine/Microsoft.OData.PublicApi.netstandard2.0.bsl
+++ b/test/PublicApiTests/BaseLine/Microsoft.OData.PublicApi.netstandard2.0.bsl
@@ -2914,6 +2914,16 @@ public sealed class Microsoft.OData.Edm.EdmUntypedStructuredType : Microsoft.ODa
Microsoft.OData.Edm.EdmTypeKind TypeKind { public virtual get; }
}
+[
+ExtensionAttribute(),
+]
+public sealed class System.Collections.Generic.ReadOnlyListExtensions {
+ [
+ ExtensionAttribute(),
+ ]
+ public static int FindLastIndex (IReadOnlyList`1 list, Func`2 predicate)
+}
+
public enum Microsoft.OData.Edm.Csdl.CsdlTarget : int {
EntityFramework = 0
OData = 1
@@ -6408,6 +6418,11 @@ public sealed class Microsoft.OData.UriParser.ODataPathExtensions {
]
public static Microsoft.OData.UriParser.ODataPath TrimEndingKeySegment (Microsoft.OData.UriParser.ODataPath path)
+ [
+ ExtensionAttribute(),
+ ]
+ public static Microsoft.OData.UriParser.ODataPath TrimEndingTypeAndKeySegments (Microsoft.OData.UriParser.ODataPath path)
+
[
ExtensionAttribute(),
]