public IActionResult Get(ODataQueryOptions <TaskModel> filter) { var tasks = repository.ListAll(); if (!string.IsNullOrWhiteSpace(filter.Filter?.RawValue)) { IEdmModel model = EdmModelHelper.GetEdmModel(); IEdmType type = model.FindDeclaredType("AspNetCoreODataWithModel.Data.Entities.Tarea"); IEdmNavigationSource source = model.FindDeclaredEntitySet("Tareas"); ODataQueryOptionParser parser = new ODataQueryOptionParser(model, type, source, new Dictionary <string, string> { { "$filter", filter.Filter?.RawValue } }); ODataQueryContext context = new ODataQueryContext(model, typeof(Tarea), filter.Context.Path); FilterQueryOption newfilter = new FilterQueryOption(filter.Filter?.RawValue, context, parser); tasks = newfilter.ApplyTo(tasks, new ODataQuerySettings()) as IQueryable <Tarea>; } var results = tasks.Select(p => mapper.Map <TaskModel>(p)); var page = new PageResult <TaskModel>(mapper.Map <IEnumerable <TaskModel> >(results.ToList()), Request.HttpContext.ODataFeature().NextLink, Request.HttpContext.ODataFeature().TotalCount); return(Ok(page)); }
/// <summary> /// Configure /// </summary> /// <param name="app"></param> /// <param name="env"></param> public static void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseSwagger(c => { c.RouteTemplate = ApiConstants.Swagger.RouteTemplate; }); app.UseSwaggerUI(c => { c.DocumentTitle = ApiConstants.Swagger.ApiName; c.SwaggerEndpoint(ApiConstants.Swagger.Endpoint, $"{ApiConstants.Swagger.ApiName} {ApiConstants.Swagger.ApiVersion}"); c.RoutePrefix = ApiConstants.Swagger.RoutePrefix; c.DocExpansion(DocExpansion.None); }); app.UseAuthorization(); app.UseProblemDetails() .UseMvc(routeBuilder => { routeBuilder.EnableDependencyInjection(); routeBuilder.Select().Filter().OrderBy().Expand().Count().MaxTop(null); routeBuilder.MapODataServiceRoute("api", "api", EdmModelHelper.GetEdmModel(app.ApplicationServices)); }); }
public void CanGetMetadataUsingProductAndCategoryModel() { IEdmModel model = EdmModelHelper.GetProductCategoryModel(); IMetadata metadata = model.GetMetadata(); Assert.NotNull(metadata); }
/// <inheritdoc/> protected override void SetOperations(OpenApiPathItem item) { IEdmEntitySet entitySet = NavigationSource as IEdmEntitySet; IEdmVocabularyAnnotatable target = entitySet; if (target == null) { target = NavigationSource as IEdmSingleton; } NavigationRestrictionsType navSourceRestrictionType = Context.Model.GetRecord <NavigationRestrictionsType>(target, CapabilitiesConstants.NavigationRestrictions); NavigationRestrictionsType navPropRestrictionType = Context.Model.GetRecord <NavigationRestrictionsType>(NavigationProperty, CapabilitiesConstants.NavigationRestrictions); NavigationPropertyRestriction restriction = navSourceRestrictionType?.RestrictedProperties? .FirstOrDefault(r => r.NavigationProperty == Path.NavigationPropertyPath()) ?? navPropRestrictionType?.RestrictedProperties?.FirstOrDefault(); // Check whether the navigation property should be part of the path if (EdmModelHelper.NavigationRestrictionsAllowsNavigability(navSourceRestrictionType, restriction) == false || EdmModelHelper.NavigationRestrictionsAllowsNavigability(navPropRestrictionType, restriction) == false) { return; } // containment: Get / (Post - Collection | Patch - Single) // non-containment: Get AddGetOperation(item, restriction); if (NavigationProperty.ContainsTarget) { if (NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many) { if (LastSegmentIsKeySegment) { UpdateRestrictionsType updateEntity = Context.Model.GetRecord <UpdateRestrictionsType>(_entityType); if (updateEntity?.IsUpdatable ?? true) { AddUpdateOperation(item, restriction); } } else { InsertRestrictionsType insert = restriction?.InsertRestrictions; if (insert?.IsInsertable ?? true) { AddOperation(item, OperationType.Post); } } } else { AddUpdateOperation(item, restriction); } } AddDeleteOperation(item, restriction); }
/// <inheritdoc/> protected override void SetResponses(OpenApiOperation operation) { OpenApiSchema schema = null; IDictionary <string, OpenApiLink> links = null; if (Context.Settings.EnableDerivedTypesReferencesForResponses) { schema = EdmModelHelper.GetDerivedTypesReferenceSchema(Singleton.EntityType(), Context.Model); } if (Context.Settings.ShowLinks) { links = Context.CreateLinks(entityType: Singleton.EntityType(), entityName: Singleton.Name, entityKind: Singleton.ContainerElementKind.ToString(), path: Path, parameters: PathParameters); } if (schema == null) { schema = new OpenApiSchema { UnresolvedReference = true, Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = Singleton.EntityType().FullName() } }; } operation.Responses = new OpenApiResponses { { Context.Settings.UseSuccessStatusCodeRange?Constants.StatusCodeClass2XX : Constants.StatusCode200, new OpenApiResponse { Description = "Retrieved entity", Content = new Dictionary <string, OpenApiMediaType> { { Constants.ApplicationJsonMediaType, new OpenApiMediaType { Schema = schema } } }, Links = links } } }; operation.AddErrorResponses(Context.Settings, false); base.SetResponses(operation); }
/// <inheritdoc/> protected override void SetResponses(OpenApiOperation operation) { OpenApiSchema schema = null; IDictionary <string, OpenApiLink> links = null; if (Context.Settings.EnableDerivedTypesReferencesForResponses) { schema = EdmModelHelper.GetDerivedTypesReferenceSchema(EntitySet.EntityType(), Context.Model); } if (Context.Settings.ShowLinks) { links = Context.CreateLinks(entityType: EntitySet.EntityType(), entityName: EntitySet.Name, entityKind: EntitySet.ContainerElementKind.ToString(), parameters: operation.Parameters); } if (schema == null) { schema = new OpenApiSchema { Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = EntitySet.EntityType().FullName() } }; } operation.Responses = new OpenApiResponses { { Constants.StatusCode200, new OpenApiResponse { Description = "Retrieved entity", Content = new Dictionary <string, OpenApiMediaType> { { Constants.ApplicationJsonMediaType, new OpenApiMediaType { Schema = schema } } }, Links = links } } }; operation.Responses.Add(Constants.StatusCodeDefault, Constants.StatusCodeDefault.GetResponse()); base.SetResponses(operation); }
/// <inheritdoc/> protected override void SetResponses(OpenApiOperation operation) { OpenApiSchema schema = null; if (Context.Settings.EnableDerivedTypesReferencesForResponses) { schema = EdmModelHelper.GetDerivedTypesReferenceSchema(Singleton.EntityType(), Context.Model); } if (schema == null) { schema = new OpenApiSchema { Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = Singleton.EntityType().FullName() } }; } operation.Responses = new OpenApiResponses { { Constants.StatusCode200, new OpenApiResponse { Description = "Retrieved entity", Content = new Dictionary <string, OpenApiMediaType> { { Constants.ApplicationJsonMediaType, new OpenApiMediaType { Schema = schema } } }, Links = Context.CreateLinks(Singleton.EntityType(), Singleton.Name) } } }; operation.Responses.Add(Constants.StatusCodeDefault, Constants.StatusCodeDefault.GetResponse()); base.SetResponses(operation); }
private OpenApiSchema GetOpenApiSchema() { if (Context.Settings.EnableDerivedTypesReferencesForRequestBody) { return(EdmModelHelper.GetDerivedTypesReferenceSchema(EntitySet.EntityType(), Context.Model)); } return(new OpenApiSchema { UnresolvedReference = true, Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = EntitySet.EntityType().FullName() } }); }
/// <inheritdoc/> protected override void SetResponses(OpenApiOperation operation) { OpenApiSchema schema = null; if (Context.Settings.EnableDerivedTypesReferencesForResponses) { schema = EdmModelHelper.GetDerivedTypesReferenceSchema(NavigationProperty.ToEntityType(), Context.Model); } if (schema == null) { schema = new OpenApiSchema { UnresolvedReference = true, Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = NavigationProperty.ToEntityType().FullName() } }; } operation.Responses = new OpenApiResponses { { Context.Settings.UseSuccessStatusCodeRange?Constants.StatusCodeClass2XX : Constants.StatusCode201, new OpenApiResponse { Description = "Created navigation property.", Content = new Dictionary <string, OpenApiMediaType> { { Constants.ApplicationJsonMediaType, new OpenApiMediaType { Schema = schema } } } } } }; operation.AddErrorResponses(Context.Settings, false); base.SetResponses(operation); }
/// <inheritdoc/> protected override void SetRequestBody(OpenApiOperation operation) { OpenApiSchema schema = null; if (Context.Settings.EnableDerivedTypesReferencesForRequestBody) { schema = EdmModelHelper.GetDerivedTypesReferenceSchema(EntitySet.EntityType(), Context.Model); } if (schema == null) { schema = new OpenApiSchema { Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = EntitySet.EntityType().FullName() } }; } // The requestBody field contains a Request Body Object for the request body // that references the schema of the entity set’s entity type in the global schemas. operation.RequestBody = new OpenApiRequestBody { Required = true, Description = "New entity", Content = new Dictionary <string, OpenApiMediaType> { { Constants.ApplicationJsonMediaType, new OpenApiMediaType { Schema = schema } } } }; base.SetRequestBody(operation); }
/// <inheritdoc/> protected override void SetRequestBody(OpenApiOperation operation) { OpenApiSchema schema = null; if (Context.Settings.EnableDerivedTypesReferencesForRequestBody) { schema = EdmModelHelper.GetDerivedTypesReferenceSchema(NavigationProperty.ToEntityType(), Context.Model); } if (schema == null) { schema = new OpenApiSchema { UnresolvedReference = true, Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = NavigationProperty.ToEntityType().FullName() } }; } operation.RequestBody = new OpenApiRequestBody { Required = true, Description = "New navigation property", Content = new Dictionary <string, OpenApiMediaType> { { Constants.ApplicationJsonMediaType, new OpenApiMediaType { Schema = schema } } } }; base.SetRequestBody(operation); }
/// <summary> /// Get the entity schema. /// </summary> /// <returns>The entity schema.</returns> private OpenApiSchema GetEntitySchema() { OpenApiSchema schema = null; if (Context.Settings.EnableDerivedTypesReferencesForRequestBody) { schema = EdmModelHelper.GetDerivedTypesReferenceSchema(EntitySet.EntityType(), Context.Model); } if (schema == null) { schema = new OpenApiSchema { Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = EntitySet.EntityType().FullName() } }; } return(schema); }
private static OpenApiSchema CreateCollectionSchema(ODataContext context, IEdmStructuredType structuredType) { OpenApiSchema schema = null; var entityType = structuredType as IEdmEntityType; if (context.Settings.EnableDerivedTypesReferencesForResponses && entityType != null) { schema = EdmModelHelper.GetDerivedTypesReferenceSchema(entityType, context.Model); } if (schema == null) { schema = new OpenApiSchema { UnresolvedReference = true, Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = entityType?.FullName() ?? structuredType.FullTypeName() } }; } return(CreateCollectionSchema(context, schema, entityType?.Name ?? structuredType.FullTypeName())); }
/// <inheritdoc/> protected override void SetResponses(OpenApiOperation operation) { OpenApiSchema schema = null; if (Context.Settings.EnableDerivedTypesReferencesForResponses) { schema = EdmModelHelper.GetDerivedTypesReferenceSchema(NavigationProperty.ToEntityType(), Context.Model); } if (schema == null) { schema = new OpenApiSchema { Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = NavigationProperty.ToEntityType().FullName() } }; } if (!LastSegmentIsKeySegment && NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many) { var properties = new Dictionary <string, OpenApiSchema> { { "value", new OpenApiSchema { Type = "array", Items = schema } } }; if (Context.Settings.EnablePagination) { properties.Add( "@odata.nextLink", new OpenApiSchema { Type = "string" }); } operation.Responses = new OpenApiResponses { { Constants.StatusCode200, new OpenApiResponse { Description = "Retrieved navigation property", Content = new Dictionary <string, OpenApiMediaType> { { Constants.ApplicationJsonMediaType, new OpenApiMediaType { Schema = new OpenApiSchema { Title = "Collection of " + NavigationProperty.ToEntityType().Name, Type = "object", Properties = properties } } } } } } }; } else { IDictionary <string, OpenApiLink> links = null; if (Context.Settings.ShowLinks) { string operationId = GetOperationId(); links = Context.CreateLinks(entityType: NavigationProperty.ToEntityType(), entityName: NavigationProperty.Name, entityKind: NavigationProperty.PropertyKind.ToString(), parameters: operation.Parameters, navPropOperationId: operationId); } operation.Responses = new OpenApiResponses { { Constants.StatusCode200, new OpenApiResponse { Description = "Retrieved navigation property", Content = new Dictionary <string, OpenApiMediaType> { { Constants.ApplicationJsonMediaType, new OpenApiMediaType { Schema = schema } } }, Links = links } } }; } operation.Responses.Add(Constants.StatusCodeDefault, Constants.StatusCodeDefault.GetResponse()); base.SetResponses(operation); }
/// <inheritdoc/> protected override void SetResponses(OpenApiOperation operation) { IDictionary <string, OpenApiLink> links = null; if (Context.Settings.ShowLinks) { string operationId = GetOperationId(); links = Context.CreateLinks(entityType: NavigationProperty.ToEntityType(), entityName: NavigationProperty.Name, entityKind: NavigationProperty.PropertyKind.ToString(), path: Path, parameters: PathParameters, navPropOperationId: operationId); } if (!LastSegmentIsKeySegment && NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many) { operation.Responses = new OpenApiResponses { { Context.Settings.UseSuccessStatusCodeRange?Constants.StatusCodeClass2XX : Constants.StatusCode200, new OpenApiResponse { UnresolvedReference = true, Reference = new OpenApiReference() { Type = ReferenceType.Response, Id = $"{NavigationProperty.ToEntityType().FullName()}{Constants.CollectionSchemaSuffix}" }, Links = links } } }; } else { OpenApiSchema schema = null; var entityType = NavigationProperty.ToEntityType(); if (Context.Settings.EnableDerivedTypesReferencesForResponses) { schema = EdmModelHelper.GetDerivedTypesReferenceSchema(entityType, Context.Model); } if (schema == null) { schema = new OpenApiSchema { UnresolvedReference = true, Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = entityType.FullName() } }; } operation.Responses = new OpenApiResponses { { Context.Settings.UseSuccessStatusCodeRange?Constants.StatusCodeClass2XX : Constants.StatusCode200, new OpenApiResponse { Description = "Retrieved navigation property", Content = new Dictionary <string, OpenApiMediaType> { { Constants.ApplicationJsonMediaType, new OpenApiMediaType { Schema = schema } } }, Links = links } } }; } operation.AddErrorResponses(Context.Settings, false); base.SetResponses(operation); }
/// <inheritdoc/> protected override void SetResponses(OpenApiOperation operation) { OpenApiSchema schema = null; if (Context.Settings.EnableDerivedTypesReferencesForResponses) { schema = EdmModelHelper.GetDerivedTypesReferenceSchema(EntitySet.EntityType(), Context.Model); } if (schema == null) { schema = new OpenApiSchema { Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = EntitySet.EntityType().FullName() } }; } var properties = new Dictionary <string, OpenApiSchema> { { "value", new OpenApiSchema { Type = "array", Items = schema } } }; if (Context.Settings.EnablePagination) { properties.Add( "@odata.nextLink", new OpenApiSchema { Type = "string" }); } operation.Responses = new OpenApiResponses { { Constants.StatusCode200, new OpenApiResponse { Description = "Retrieved entities", Content = new Dictionary <string, OpenApiMediaType> { { Constants.ApplicationJsonMediaType, new OpenApiMediaType { Schema = new OpenApiSchema { Title = "Collection of " + EntitySet.EntityType().Name, Type = "object", Properties = properties } } } }, Links = Context.CreateLinks(EntitySet.EntityType(), EntitySet.Name) } } }; operation.Responses.Add(Constants.StatusCodeDefault, Constants.StatusCodeDefault.GetResponse()); base.SetResponses(operation); }
private static Task ExecuteJsonBatchRequest() { return(Task.Run(async() => { // Act HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUri); request.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json")); string requestJson = @" { ""requests"": [{ ""id"": ""-1"", ""method"": ""GET"", ""url"": """ + absoluteUri + @""", ""headers"": { ""OData-Version"": ""4.0"", ""Content-Type"": ""application/json;odata.metadata=minimal"", ""Accept"": ""application/json;odata.metadata=minimal"" } }, { ""id"": ""0"", ""atomicityGroup"": ""f7de7314-2f3d-4422-b840-ada6d6de0f18"", ""method"": ""PATCH"", ""url"": """ + absoluteUri + "(6)" + @""", ""headers"": { ""OData-Version"": ""4.0"", ""Content-Type"": ""application/json;odata.metadata=minimal"", ""Accept"": ""application/json;odata.metadata=minimal"" }, ""body"": { ""Name"":""PatchedByJsonBatch_0"" } }, { ""id"": ""1"", ""atomicityGroup"": ""f7de7314-2f3d-4422-b840-ada6d6de0f18"", ""method"": ""POST"", ""url"": """ + absoluteUri + @""", ""headers"": { ""OData-Version"": ""4.0"", ""Content-Type"": ""application/json;odata.metadata=minimal"", ""Accept"": ""application/json;odata.metadata=minimal"" }, ""body"": { ""Id"":1001, ""Name"":""CreatedByJsonBatch_11"" } }, { ""id"": ""2"", ""atomicityGroup"": ""f7de7314-2f3d-4422-b840-ada6d6de0f18"", ""method"": ""POST"", ""url"": """ + absoluteUri + @""", ""headers"": { ""OData-Version"": ""4.0"", ""Content-Type"": ""application/json;odata.metadata=minimal"", ""Accept"": ""application/json;odata.metadata=minimal"" }, ""body"": { ""Id"":1002, ""Name"":""CreatedByJsonBatch_12"" } }, { ""id"": ""3"", ""method"": ""POST"", ""url"": """ + absoluteUri + @""", ""headers"": { ""OData-Version"": ""4.0"", ""Content-Type"": ""application/json;odata.metadata=minimal"", ""Accept"": ""application/json;odata.metadata=minimal"" }, ""body"": { ""Id"": 1003, ""Name"":""CreatedByJsonBatch_3"" } } ] }"; HttpContent content = new StringContent(requestJson); content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json"); request.Content = content; Console.WriteLine("Sending batch request...\r\n {0}", requestJson); HttpResponseMessage response = await httpClient.SendAsync(request); var stream = await response.Content.ReadAsStreamAsync(); Console.WriteLine("Batch response code: {0}", response.StatusCode); Console.WriteLine("Batch response format: {0}", response.Content.Headers.ContentType.MediaType.ToString()); IODataResponseMessage odataResponseMessage = new ODataMessageWrapper(stream, response.Content.Headers); int subResponseCount = 0; using (var messageReader = new ODataMessageReader(odataResponseMessage, new ODataMessageReaderSettings(), EdmModelHelper.GetModel())) { var batchReader = messageReader.CreateODataBatchReader(); while (batchReader.Read()) { switch (batchReader.State) { case ODataBatchReaderState.Operation: var operationMessage = batchReader.CreateOperationResponseMessage(); subResponseCount++; Console.WriteLine("\tOperation: ContentId: {0}, StatusCode: {1}, GroupId: {2}", operationMessage.ContentId, operationMessage.StatusCode, operationMessage.GroupId ?? "null"); break; } } } Console.WriteLine("\r\nTotal requests count: {0}", subResponseCount); })); }
/// <summary> /// Retrieve the path for <see cref="IEdmNavigationProperty"/>. /// </summary> /// <param name="navigationProperty">The navigation property.</param> /// <param name="count">The count restrictions.</param> /// <param name="currentPath">The current OData path.</param> /// <param name="convertSettings">The settings for the current conversion.</param> /// <param name="visitedNavigationProperties">A stack that holds the visited navigation properties in the <paramref name="currentPath"/>.</param> private void RetrieveNavigationPropertyPaths( IEdmNavigationProperty navigationProperty, CountRestrictionsType count, ODataPath currentPath, OpenApiConvertSettings convertSettings, Stack <string> visitedNavigationProperties = null) { Debug.Assert(navigationProperty != null); Debug.Assert(currentPath != null); if (visitedNavigationProperties == null) { visitedNavigationProperties = new(); } string navPropFullyQualifiedName = $"{navigationProperty.DeclaringType.FullTypeName()}/{navigationProperty.Name}"; // Check whether the navigation property has already been navigated in the path. if (visitedNavigationProperties.Contains(navPropFullyQualifiedName)) { return; } // Get the annotatable navigation source for this navigation property. IEdmVocabularyAnnotatable annotatableNavigationSource = (currentPath.FirstSegment as ODataNavigationSourceSegment)?.NavigationSource as IEdmVocabularyAnnotatable; NavigationRestrictionsType navSourceRestrictionType = null; NavigationRestrictionsType navPropRestrictionType = null; // Get the NavigationRestrictions referenced by this navigation property: Can be defined in the navigation source or in-lined in the navigation property. if (annotatableNavigationSource != null) { navSourceRestrictionType = _model.GetRecord <NavigationRestrictionsType>(annotatableNavigationSource, CapabilitiesConstants.NavigationRestrictions); navPropRestrictionType = _model.GetRecord <NavigationRestrictionsType>(navigationProperty, CapabilitiesConstants.NavigationRestrictions); } NavigationPropertyRestriction restriction = navSourceRestrictionType?.RestrictedProperties? .FirstOrDefault(r => r.NavigationProperty == currentPath.NavigationPropertyPath(navigationProperty.Name)) ?? navPropRestrictionType?.RestrictedProperties?.FirstOrDefault(); // Check whether the navigation property should be part of the path if (!EdmModelHelper.NavigationRestrictionsAllowsNavigability(navSourceRestrictionType, restriction) || !EdmModelHelper.NavigationRestrictionsAllowsNavigability(navPropRestrictionType, restriction)) { return; } // Whether to expand the navigation property. bool shouldExpand = navigationProperty.ContainsTarget; // Append a navigation property. currentPath.Push(new ODataNavigationPropertySegment(navigationProperty)); AppendPath(currentPath.Clone()); visitedNavigationProperties.Push(navPropFullyQualifiedName); // Check whether a collection-valued navigation property should be indexed by key value(s). bool indexableByKey = restriction?.IndexableByKey ?? true; if (indexableByKey) { IEdmEntityType navEntityType = navigationProperty.ToEntityType(); var targetsMany = navigationProperty.TargetMultiplicity() == EdmMultiplicity.Many; var propertyPath = navigationProperty.GetPartnerPath()?.Path; var propertyPathIsEmpty = string.IsNullOrEmpty(propertyPath); if (targetsMany) { if (propertyPathIsEmpty || (count?.IsNonCountableNavigationProperty(propertyPath) ?? true)) { // ~/entityset/{key}/collection-valued-Nav/$count CreateCountPath(currentPath, convertSettings); } } // ~/entityset/{key}/collection-valued-Nav/subtype // ~/entityset/{key}/single-valued-Nav/subtype CreateTypeCastPaths(currentPath, convertSettings, navEntityType, navigationProperty, targetsMany); if ((navSourceRestrictionType?.Referenceable ?? false) || (navPropRestrictionType?.Referenceable ?? false)) { // Referenceable navigation properties // Single-Valued: ~/entityset/{key}/single-valued-Nav/$ref // Collection-valued: ~/entityset/{key}/collection-valued-Nav/$ref?$id='{navKey}' CreateRefPath(currentPath); if (targetsMany) { // Collection-valued: DELETE ~/entityset/{key}/collection-valued-Nav/{key}/$ref currentPath.Push(new ODataKeySegment(navEntityType)); CreateRefPath(currentPath); CreateTypeCastPaths(currentPath, convertSettings, navEntityType, navigationProperty, false); // ~/entityset/{key}/collection-valued-Nav/{id}/subtype } // Get possible stream paths for the navigation entity type RetrieveMediaEntityStreamPaths(navEntityType, currentPath); // Get the paths for the navigation property entity type properties of type complex RetrieveComplexPropertyPaths(navEntityType, currentPath, convertSettings); } else { // append a navigation property key. if (targetsMany) { currentPath.Push(new ODataKeySegment(navEntityType)); AppendPath(currentPath.Clone()); CreateTypeCastPaths(currentPath, convertSettings, navEntityType, navigationProperty, false); // ~/entityset/{key}/collection-valued-Nav/{id}/subtype } // Get possible stream paths for the navigation entity type RetrieveMediaEntityStreamPaths(navEntityType, currentPath); // Get the paths for the navigation property entity type properties of type complex RetrieveComplexPropertyPaths(navEntityType, currentPath, convertSettings); if (shouldExpand) { // expand to sub navigation properties foreach (IEdmNavigationProperty subNavProperty in navEntityType.DeclaredNavigationProperties()) { if (CanFilter(subNavProperty)) { RetrieveNavigationPropertyPaths(subNavProperty, count, currentPath, convertSettings, visitedNavigationProperties); } } } } if (targetsMany) { currentPath.Pop(); } } currentPath.Pop(); visitedNavigationProperties.Pop(); }