Ejemplo n.º 1
0
        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));
        }
Ejemplo n.º 2
0
        /// <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));
            });
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 5
0
        /// <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);
        }
Ejemplo n.º 6
0
        /// <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);
        }
Ejemplo n.º 8
0
        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()
                }
            });
        }
Ejemplo n.º 9
0
        /// <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);
        }
Ejemplo n.º 11
0
        /// <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);
        }
Ejemplo n.º 12
0
        /// <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);
        }
Ejemplo n.º 15
0
        /// <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);
        }
Ejemplo n.º 16
0
        /// <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);
        }
Ejemplo n.º 17
0
        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();
        }