From e0eb6bebbecea6b3d470eb2b6029ab96842d927d Mon Sep 17 00:00:00 2001 From: Giuliano Barberi Date: Mon, 4 Apr 2022 05:03:31 -0700 Subject: [PATCH 01/21] Fixing CORS attribute (#544) Registering selectors with CORS when controller/action use CORS attributes. Fixes #534. Co-authored-by: Giuliano Barberi --- .../Extensions/ActionModelExtensions.cs | 21 ++++++--- .../Extensions/ActionModelExtensionsTests.cs | 44 ++++++++++++++++++- 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/src/Microsoft.AspNetCore.OData/Extensions/ActionModelExtensions.cs b/src/Microsoft.AspNetCore.OData/Extensions/ActionModelExtensions.cs index 83f5edb9c..788b177ca 100644 --- a/src/Microsoft.AspNetCore.OData/Extensions/ActionModelExtensions.cs +++ b/src/Microsoft.AspNetCore.OData/Extensions/ActionModelExtensions.cs @@ -9,6 +9,7 @@ using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Linq; +using Microsoft.AspNetCore.Cors.Infrastructure; using Microsoft.AspNetCore.Mvc.ActionConstraints; using Microsoft.AspNetCore.Mvc.ApplicationModels; using Microsoft.AspNetCore.Mvc.Routing; @@ -173,7 +174,13 @@ public static void AddSelector(this ActionModel action, string httpMethods, stri // let's always create new selector model for action. // Since the new created selector model is absolute attribute route, the controller attribute route doesn't apply to this selector model. bool hasAttributeRouteOnController = action.Controller.Selectors.Any(s => s.AttributeRouteModel != null); - + + // Check if CORS attribute is specified on action. New selectors need to be registered with CORS support. + bool acceptPreflight = action.Controller.Attributes.OfType().Any() || + action.Controller.Attributes.OfType().Any() || + action.Attributes.OfType().Any() || + action.Attributes.OfType().Any(); + // If the methods have different case sensitive, for example, "get", "Get", in the ASP.NET Core 3.1, // It will throw "An item with the same key has already been added. Key: GET", in // HttpMethodMatcherPolicy.BuildJumpTable(Int32 exitDestination, IReadOnlyList`1 edges) @@ -189,13 +196,13 @@ public static void AddSelector(this ActionModel action, string httpMethods, stri if (hasAttributeRouteOnController || selectorModel == null) { // Create a new selector model. - selectorModel = CreateSelectorModel(action, methods); + selectorModel = CreateSelectorModel(action, methods, acceptPreflight); action.Selectors.Add(selectorModel); } else { // Update the existing non attribute routing selector model. - selectorModel = UpdateSelectorModel(selectorModel, methods); + selectorModel = UpdateSelectorModel(selectorModel, methods, acceptPreflight); } ODataRoutingMetadata odataMetadata = new ODataRoutingMetadata(prefix, model, path); @@ -216,7 +223,7 @@ public static void AddSelector(this ActionModel action, string httpMethods, stri } } - internal static SelectorModel UpdateSelectorModel(SelectorModel selectorModel, string[] httpMethods) + internal static SelectorModel UpdateSelectorModel(SelectorModel selectorModel, string[] httpMethods, bool acceptPreflight) { Contract.Assert(selectorModel != null); @@ -257,7 +264,7 @@ internal static SelectorModel UpdateSelectorModel(SelectorModel selectorModel, s // append the http method metadata. Contract.Assert(httpMethods.Length >= 1); selectorModel.ActionConstraints.Add(new HttpMethodActionConstraint(httpMethods)); - selectorModel.EndpointMetadata.Add(new HttpMethodMetadata(httpMethods)); + selectorModel.EndpointMetadata.Add(new HttpMethodMetadata(httpMethods, acceptPreflight)); // append controller attributes to action selector model? -- NO // Be noted: https://github.com/dotnet/aspnetcore/blob/main/src/Mvc/Mvc.Core/src/ApplicationModels/ActionAttributeRouteModel.cs#L74-L75 @@ -265,7 +272,7 @@ internal static SelectorModel UpdateSelectorModel(SelectorModel selectorModel, s return selectorModel; } - internal static SelectorModel CreateSelectorModel(ActionModel actionModel, string[] httpMethods) + internal static SelectorModel CreateSelectorModel(ActionModel actionModel, string[] httpMethods, bool acceptPreflight) { Contract.Assert(actionModel != null); @@ -309,7 +316,7 @@ internal static SelectorModel CreateSelectorModel(ActionModel actionModel, strin Contract.Assert(httpMethods.Length >= 1); selectorModel.ActionConstraints.Add(new HttpMethodActionConstraint(httpMethods)); - selectorModel.EndpointMetadata.Add(new HttpMethodMetadata(httpMethods)); + selectorModel.EndpointMetadata.Add(new HttpMethodMetadata(httpMethods, acceptPreflight)); // append controller attributes to action selector model? -- NO // Be noted: https://github.com/dotnet/aspnetcore/blob/main/src/Mvc/Mvc.Core/src/ApplicationModels/ActionAttributeRouteModel.cs#L74-L75 diff --git a/test/Microsoft.AspNetCore.OData.Tests/Extensions/ActionModelExtensionsTests.cs b/test/Microsoft.AspNetCore.OData.Tests/Extensions/ActionModelExtensionsTests.cs index 0dd830dbd..655ead2fb 100644 --- a/test/Microsoft.AspNetCore.OData.Tests/Extensions/ActionModelExtensionsTests.cs +++ b/test/Microsoft.AspNetCore.OData.Tests/Extensions/ActionModelExtensionsTests.cs @@ -5,12 +5,17 @@ // //------------------------------------------------------------------------------ +using System; using System.Collections.Generic; +using System.Linq; using System.Reflection; +using Microsoft.AspNetCore.Cors; using Microsoft.AspNetCore.Mvc.ApplicationModels; using Microsoft.AspNetCore.OData.Extensions; using Microsoft.AspNetCore.OData.Routing.Attributes; +using Microsoft.AspNetCore.OData.Routing.Template; using Microsoft.AspNetCore.OData.Tests.Commons; +using Microsoft.AspNetCore.Routing; using Microsoft.OData.Edm; using Moq; using Xunit; @@ -113,15 +118,50 @@ public void AddSelector_ThrowsArgumentNull_ForInputParameter() IEdmModel model = new Mock().Object; ExceptionAssert.ThrowsArgumentNull(() => action.AddSelector(httpMethods, null, model, null), "path"); } + + [Theory] + [InlineData(typeof(TestController), "Get", true)] + [InlineData(typeof(TestController), "Create", true)] + [InlineData(typeof(TestController), "Index", false)] + [InlineData(typeof(CorsTestController), "Index", true)] + public void AddSelector_AddsCors_ForActionsWithCorsAttribute(Type controllerType, string actionName, bool expectedCorsSetting) + { + // Arrange + IEdmModel model = new Mock().Object; + MethodInfo methodInfo = controllerType.GetMethod(actionName); + ActionModel action = methodInfo.BuildActionModel(); + action.Controller = ControllerModelHelpers.BuildControllerModel(controllerType); + + // Act + action.AddSelector("Get", string.Empty, model, new ODataPathTemplate(CountSegmentTemplate.Instance)); + + // Assert + SelectorModel newSelector = action.Selectors.FirstOrDefault(); + Assert.NotNull(newSelector); + HttpMethodMetadata httpMethodMetadata = newSelector.EndpointMetadata.OfType().FirstOrDefault(); + Assert.NotNull(httpMethodMetadata); + Assert.Equal(httpMethodMetadata.AcceptCorsPreflight, expectedCorsSetting); + } } internal class TestController { public void Index(int id) - { - } + { } + [EnableCors] public void Get(int key) { } + + [DisableCors] + public void Create() + { } + } + + [EnableCors] + internal class CorsTestController + { + public void Index(int id) + { } } } From 4676237520ebed2b73cd1f1531a1a175c1213207 Mon Sep 17 00:00:00 2001 From: Kamil Jaworski Date: Thu, 14 Apr 2022 02:06:28 +0200 Subject: [PATCH 02/21] EnableQueryAttribute - static GetModel changed back to virtual (#553) * GetModel made virtual again * Adjusted PublicApi tests * Updated Unshipped.txt file Co-authored-by: Kamil Jaworski --- src/Microsoft.AspNetCore.OData/PublicAPI.Unshipped.txt | 2 +- .../Query/EnableQueryAttribute.cs | 6 +++--- .../PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net5.bsl | 2 +- .../Microsoft.AspNetCore.OData.PublicApi.NetCore31.bsl | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.AspNetCore.OData/PublicAPI.Unshipped.txt b/src/Microsoft.AspNetCore.OData/PublicAPI.Unshipped.txt index 8fa716534..e40289656 100644 --- a/src/Microsoft.AspNetCore.OData/PublicAPI.Unshipped.txt +++ b/src/Microsoft.AspNetCore.OData/PublicAPI.Unshipped.txt @@ -1618,7 +1618,6 @@ static Microsoft.AspNetCore.OData.ODataServiceCollectionExtensions.AddODataQuery static Microsoft.AspNetCore.OData.ODataUriFunctions.AddCustomUriFunction(string functionName, Microsoft.OData.UriParser.FunctionSignatureWithReturnType functionSignature, System.Reflection.MethodInfo methodInfo) -> void static Microsoft.AspNetCore.OData.ODataUriFunctions.RemoveCustomUriFunction(string functionName, Microsoft.OData.UriParser.FunctionSignatureWithReturnType functionSignature, System.Reflection.MethodInfo methodInfo) -> bool static Microsoft.AspNetCore.OData.Query.EnableQueryAttribute.CreateErrorResponse(string message, System.Exception exception = null) -> Microsoft.AspNetCore.Mvc.SerializableError -static Microsoft.AspNetCore.OData.Query.EnableQueryAttribute.GetModel(System.Type elementClrType, Microsoft.AspNetCore.Http.HttpRequest request, Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor) -> Microsoft.OData.Edm.IEdmModel static Microsoft.AspNetCore.OData.Query.Expressions.BinderExtensions.ApplyBind(this Microsoft.AspNetCore.OData.Query.Expressions.IFilterBinder binder, System.Collections.IEnumerable query, Microsoft.OData.UriParser.FilterClause filterClause, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) -> System.Collections.IEnumerable static Microsoft.AspNetCore.OData.Query.Expressions.BinderExtensions.ApplyBind(this Microsoft.AspNetCore.OData.Query.Expressions.IFilterBinder binder, System.Linq.Expressions.Expression source, Microsoft.OData.UriParser.FilterClause filterClause, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) -> System.Linq.Expressions.Expression static Microsoft.AspNetCore.OData.Query.Expressions.BinderExtensions.ApplyBind(this Microsoft.AspNetCore.OData.Query.Expressions.IFilterBinder binder, System.Linq.IQueryable query, Microsoft.OData.UriParser.FilterClause filterClause, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) -> System.Linq.IQueryable @@ -1719,6 +1718,7 @@ virtual Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerProvid virtual Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerProvider.GetODataPayloadSerializer(System.Type type, Microsoft.AspNetCore.Http.HttpRequest request) -> Microsoft.AspNetCore.OData.Formatter.Serialization.IODataSerializer virtual Microsoft.AspNetCore.OData.Query.EnableQueryAttribute.ApplyQuery(object entity, Microsoft.AspNetCore.OData.Query.ODataQueryOptions queryOptions) -> object virtual Microsoft.AspNetCore.OData.Query.EnableQueryAttribute.ApplyQuery(System.Linq.IQueryable queryable, Microsoft.AspNetCore.OData.Query.ODataQueryOptions queryOptions) -> System.Linq.IQueryable +virtual Microsoft.AspNetCore.OData.Query.EnableQueryAttribute.GetModel(System.Type elementClrType, Microsoft.AspNetCore.Http.HttpRequest request, Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor) -> Microsoft.OData.Edm.IEdmModel virtual Microsoft.AspNetCore.OData.Query.EnableQueryAttribute.ValidateQuery(Microsoft.AspNetCore.Http.HttpRequest request, Microsoft.AspNetCore.OData.Query.ODataQueryOptions queryOptions) -> void virtual Microsoft.AspNetCore.OData.Query.ETag.ApplyTo(System.Linq.IQueryable query) -> System.Linq.IQueryable virtual Microsoft.AspNetCore.OData.Query.Expressions.ExpressionBinderBase.BindCollectionConstantNode(Microsoft.OData.UriParser.CollectionConstantNode node) -> System.Linq.Expressions.Expression diff --git a/src/Microsoft.AspNetCore.OData/Query/EnableQueryAttribute.cs b/src/Microsoft.AspNetCore.OData/Query/EnableQueryAttribute.cs index 9a976865b..31f12d35b 100644 --- a/src/Microsoft.AspNetCore.OData/Query/EnableQueryAttribute.cs +++ b/src/Microsoft.AspNetCore.OData/Query/EnableQueryAttribute.cs @@ -613,7 +613,7 @@ internal static void ValidateSelectExpandOnly(ODataQueryOptions queryOptions) /// The action context, i.e. action and controller name. /// The OData path. /// - private static ODataQueryContext GetODataQueryContext( + private ODataQueryContext GetODataQueryContext( object responseValue, IQueryable singleResultCollection, ControllerActionDescriptor actionDescriptor, @@ -715,7 +715,7 @@ public virtual void ValidateQuery(HttpRequest request, ODataQueryOptions queryOp /// The action context, i.e. action and controller name. /// The Http request. /// true/false - private static bool ContainsAutoSelectExpandProperty(object responseValue, IQueryable singleResultCollection, + private bool ContainsAutoSelectExpandProperty(object responseValue, IQueryable singleResultCollection, ControllerActionDescriptor actionDescriptor, HttpRequest request) { Type elementClrType = GetElementType(responseValue, singleResultCollection, actionDescriptor); @@ -758,7 +758,7 @@ private static bool ContainsAutoSelectExpandProperty(object responseValue, IQuer /// The request message to retrieve a model for. /// The action descriptor for the action being queried on. /// The EDM model for the given type and request. - public static IEdmModel GetModel( + public virtual IEdmModel GetModel( Type elementClrType, HttpRequest request, ActionDescriptor actionDescriptor) diff --git a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net5.bsl b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net5.bsl index a59f8bdc6..87b1c80ee 100644 --- a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net5.bsl +++ b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net5.bsl @@ -1301,7 +1301,7 @@ public class Microsoft.AspNetCore.OData.Query.EnableQueryAttribute : Microsoft.A public virtual System.Linq.IQueryable ApplyQuery (System.Linq.IQueryable queryable, Microsoft.AspNetCore.OData.Query.ODataQueryOptions queryOptions) public virtual object ApplyQuery (object entity, Microsoft.AspNetCore.OData.Query.ODataQueryOptions queryOptions) public static Microsoft.AspNetCore.Mvc.SerializableError CreateErrorResponse (string message, params System.Exception exception) - public static Microsoft.OData.Edm.IEdmModel GetModel (System.Type elementClrType, Microsoft.AspNetCore.Http.HttpRequest request, Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor) + public virtual Microsoft.OData.Edm.IEdmModel GetModel (System.Type elementClrType, Microsoft.AspNetCore.Http.HttpRequest request, Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor) public virtual void OnActionExecuted (Microsoft.AspNetCore.Mvc.Filters.ActionExecutedContext actionExecutedContext) public virtual void OnActionExecuting (Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext actionExecutingContext) public virtual void ValidateQuery (Microsoft.AspNetCore.Http.HttpRequest request, Microsoft.AspNetCore.OData.Query.ODataQueryOptions queryOptions) diff --git a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.NetCore31.bsl b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.NetCore31.bsl index a59f8bdc6..87b1c80ee 100644 --- a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.NetCore31.bsl +++ b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.NetCore31.bsl @@ -1301,7 +1301,7 @@ public class Microsoft.AspNetCore.OData.Query.EnableQueryAttribute : Microsoft.A public virtual System.Linq.IQueryable ApplyQuery (System.Linq.IQueryable queryable, Microsoft.AspNetCore.OData.Query.ODataQueryOptions queryOptions) public virtual object ApplyQuery (object entity, Microsoft.AspNetCore.OData.Query.ODataQueryOptions queryOptions) public static Microsoft.AspNetCore.Mvc.SerializableError CreateErrorResponse (string message, params System.Exception exception) - public static Microsoft.OData.Edm.IEdmModel GetModel (System.Type elementClrType, Microsoft.AspNetCore.Http.HttpRequest request, Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor) + public virtual Microsoft.OData.Edm.IEdmModel GetModel (System.Type elementClrType, Microsoft.AspNetCore.Http.HttpRequest request, Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor) public virtual void OnActionExecuted (Microsoft.AspNetCore.Mvc.Filters.ActionExecutedContext actionExecutedContext) public virtual void OnActionExecuting (Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext actionExecutingContext) public virtual void ValidateQuery (Microsoft.AspNetCore.Http.HttpRequest request, Microsoft.AspNetCore.OData.Query.ODataQueryOptions queryOptions) From ea6c4f2ef64afdb78460424f950f297c87d20a78 Mon Sep 17 00:00:00 2001 From: Sam Xu Date: Thu, 14 Apr 2022 10:30:22 -0700 Subject: [PATCH 03/21] Update the version to 8.0.9 --- tool/builder.versions.settings.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tool/builder.versions.settings.targets b/tool/builder.versions.settings.targets index eef98dee8..834768080 100644 --- a/tool/builder.versions.settings.targets +++ b/tool/builder.versions.settings.targets @@ -3,7 +3,7 @@ 8 0 - 8 + 9 From 9b455016630ad284c3b074606d3d17eca28c37d7 Mon Sep 17 00:00:00 2001 From: Sam Xu Date: Thu, 14 Apr 2022 11:20:27 -0700 Subject: [PATCH 04/21] Fix the build warning in the tests project --- .../Routing/Conventions/ActionRoutingConventionTests.cs | 2 +- .../Routing/Conventions/FunctionRoutingConventionTests.cs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/test/Microsoft.AspNetCore.OData.Tests/Routing/Conventions/ActionRoutingConventionTests.cs b/test/Microsoft.AspNetCore.OData.Tests/Routing/Conventions/ActionRoutingConventionTests.cs index efe82ba13..d790c1da4 100644 --- a/test/Microsoft.AspNetCore.OData.Tests/Routing/Conventions/ActionRoutingConventionTests.cs +++ b/test/Microsoft.AspNetCore.OData.Tests/Routing/Conventions/ActionRoutingConventionTests.cs @@ -305,7 +305,6 @@ public void ActionRoutingConventionTestDataWithCaseInsensitiveActionNameRunsAsEx // Act ActionConvention.AppliesToAction(context); - // Assert Assert.Equal(templates.Length, action.Selectors.Count); Assert.Equal(templates, action.Selectors.Select(s => s.AttributeRouteModel.Template)); @@ -328,6 +327,7 @@ public void ActionRoutingConventionDoesCaseSensitiveMatchingByDefault(Type contr // Assert SelectorModel selector = Assert.Single(action.Selectors); Assert.Null(selector.AttributeRouteModel); + Assert.NotEmpty(templates); } [Theory] diff --git a/test/Microsoft.AspNetCore.OData.Tests/Routing/Conventions/FunctionRoutingConventionTests.cs b/test/Microsoft.AspNetCore.OData.Tests/Routing/Conventions/FunctionRoutingConventionTests.cs index f139d4c40..34d95d5a9 100644 --- a/test/Microsoft.AspNetCore.OData.Tests/Routing/Conventions/FunctionRoutingConventionTests.cs +++ b/test/Microsoft.AspNetCore.OData.Tests/Routing/Conventions/FunctionRoutingConventionTests.cs @@ -288,6 +288,7 @@ public void FunctionRoutingConventionCaseSensitiveByDefault(Type controllerType, // Assert SelectorModel selector = Assert.Single(action.Selectors); Assert.Null(selector.AttributeRouteModel); + Assert.NotEmpty(templates); } public static TheoryDataSet OverloadFunctionTestData From 3c7e83f454709a3cd943b655f68da4261a1660fe Mon Sep 17 00:00:00 2001 From: Sam Xu Date: Thu, 21 Apr 2022 11:19:56 -0700 Subject: [PATCH 05/21] Issue #567: Escape character , for example ('/') is not proper handled at key or function in quoted string --- .../Controllers/PeopleController.cs | 3 +- .../Routing/Template/KeySegmentTemplate.cs | 2 + .../Template/SegmentTemplateHelpers.cs | 1 + .../Template/FunctionSegmentTemplateTests.cs | 34 ++++++++++++++ .../Template/KeySegmentTemplateTests.cs | 47 +++++++++++++++++++ 5 files changed, 86 insertions(+), 1 deletion(-) diff --git a/sample/ODataRoutingSample/Controllers/PeopleController.cs b/sample/ODataRoutingSample/Controllers/PeopleController.cs index 4d3d8b400..34b577e5c 100644 --- a/sample/ODataRoutingSample/Controllers/PeopleController.cs +++ b/sample/ODataRoutingSample/Controllers/PeopleController.cs @@ -21,7 +21,7 @@ public class PeopleController : ControllerBase new Person { FirstName = "Goods", - LastName = "Zhangg", + LastName = "Zha/ngg", }, new Person { @@ -42,6 +42,7 @@ public IActionResult Get(CancellationToken token) return Ok(_persons); } + // People(FirstName='Goods',LastName='Zha%2Fngg') [HttpGet] [EnableQuery] public IActionResult Get(string keyFirstName, string keyLastName) diff --git a/src/Microsoft.AspNetCore.OData/Routing/Template/KeySegmentTemplate.cs b/src/Microsoft.AspNetCore.OData/Routing/Template/KeySegmentTemplate.cs index dc282ffdd..b139b7cf5 100644 --- a/src/Microsoft.AspNetCore.OData/Routing/Template/KeySegmentTemplate.cs +++ b/src/Microsoft.AspNetCore.OData/Routing/Template/KeySegmentTemplate.cs @@ -5,6 +5,7 @@ // //------------------------------------------------------------------------------ +using System; using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Linq; @@ -172,6 +173,7 @@ public override bool TryTranslate(ODataTemplateTranslateContext context) IEdmTypeReference edmType = keyProperty.Type; string strValue = rawValue as string; string newStrValue = context.GetParameterAliasOrSelf(strValue); + newStrValue = Uri.UnescapeDataString(newStrValue); if (newStrValue != strValue) { updateValues[templateName] = newStrValue; diff --git a/src/Microsoft.AspNetCore.OData/Routing/Template/SegmentTemplateHelpers.cs b/src/Microsoft.AspNetCore.OData/Routing/Template/SegmentTemplateHelpers.cs index f65a34b47..46e44a38f 100644 --- a/src/Microsoft.AspNetCore.OData/Routing/Template/SegmentTemplateHelpers.cs +++ b/src/Microsoft.AspNetCore.OData/Routing/Template/SegmentTemplateHelpers.cs @@ -58,6 +58,7 @@ public static IList Match(ODataTemplateTranslateConte { string strValue = rawValue as string; string newStrValue = context.GetParameterAliasOrSelf(strValue); + newStrValue = Uri.UnescapeDataString(newStrValue); if (newStrValue != strValue) { updatedValues[parameterTemp] = newStrValue; diff --git a/test/Microsoft.AspNetCore.OData.Tests/Routing/Template/FunctionSegmentTemplateTests.cs b/test/Microsoft.AspNetCore.OData.Tests/Routing/Template/FunctionSegmentTemplateTests.cs index ee848b2d8..3c18a2019 100644 --- a/test/Microsoft.AspNetCore.OData.Tests/Routing/Template/FunctionSegmentTemplateTests.cs +++ b/test/Microsoft.AspNetCore.OData.Tests/Routing/Template/FunctionSegmentTemplateTests.cs @@ -370,5 +370,39 @@ public void TryTranslateFunctionSegmentTemplate_ReturnsODataFunctionSegment_With Assert.Equal(42, e.Value); }); } + + [Fact] + public void TryTranslateFunctionSegmentTemplate_ReturnsODataFunctionSegment_UsingEscapedString() + { + // Arrange + var primitive = EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.String, false); + EdmFunction function = new EdmFunction("NS", "MyFunction", primitive, true, null, false); + function.AddParameter("bindingParameter", primitive); + function.AddParameter("name", primitive); + + FunctionSegmentTemplate template = new FunctionSegmentTemplate(function, null); + EdmModel edmModel = new EdmModel(); + edmModel.AddElement(function); + + RouteValueDictionary routeValue = new RouteValueDictionary(new { name = "'Ji%2FChange%23%20T'" }); + + ODataTemplateTranslateContext context = new ODataTemplateTranslateContext + { + RouteValues = routeValue, + Model = edmModel + }; + + // Act + bool ok = template.TryTranslate(context); + + // Assert + Assert.True(ok); + ODataPathSegment actual = Assert.Single(context.Segments); + OperationSegment functionSegment = Assert.IsType(actual); + Assert.Same(function, functionSegment.Operations.First()); + var parameter = Assert.Single(functionSegment.Parameters); + Assert.Equal("name", parameter.Name); + Assert.Equal("Ji/Change# T", parameter.Value.ToString()); + } } } diff --git a/test/Microsoft.AspNetCore.OData.Tests/Routing/Template/KeySegmentTemplateTests.cs b/test/Microsoft.AspNetCore.OData.Tests/Routing/Template/KeySegmentTemplateTests.cs index d33dbeb7e..d79a635fe 100644 --- a/test/Microsoft.AspNetCore.OData.Tests/Routing/Template/KeySegmentTemplateTests.cs +++ b/test/Microsoft.AspNetCore.OData.Tests/Routing/Template/KeySegmentTemplateTests.cs @@ -484,6 +484,53 @@ public void TryTranslateKeySegmentTemplate_WorksWithKeyParametersAlias() Assert.Equal(42, actualKeys.Value); } + [Fact] + public void TryTranslateKeySegmentTemplate_WorksWithKeyValue_UsingEscapedString() + { + // Arrange + EdmModel model = new EdmModel(); + EdmEntityType customerType = new EdmEntityType("NS", "Customer"); + EdmStructuralProperty firstName = customerType.AddStructuralProperty("FirstName", EdmPrimitiveTypeKind.String); + EdmStructuralProperty lastName = customerType.AddStructuralProperty("LastName", EdmPrimitiveTypeKind.String); + customerType.AddKeys(firstName, lastName); + model.AddElement(customerType); + EdmEntityContainer container = new EdmEntityContainer("NS", "Default"); + EdmEntitySet customers = container.AddEntitySet("Customers", customerType); + model.AddElement(container); + RouteValueDictionary routeValueDictionary = new RouteValueDictionary(new { First = "'Zhang'", Last = "'Gan%2Fnng%23%20T'" }); + IDictionary keys = new Dictionary + { + { "FirstName", "{first}" }, + { "LastName", "{last}" } + }; + KeySegmentTemplate template = new KeySegmentTemplate(keys, customerType, customers); + + ODataTemplateTranslateContext context = new ODataTemplateTranslateContext + { + RouteValues = routeValueDictionary, + Model = model + }; + + // Act + bool ok = template.TryTranslate(context); + + // Assert + Assert.True(ok); + ODataPathSegment actual = Assert.Single(context.Segments); + KeySegment keySegment = Assert.IsType(actual); + Assert.Collection(keySegment.Keys, + e => + { + Assert.Equal("FirstName", e.Key); + Assert.Equal("Zhang", e.Value); + }, + e => + { + Assert.Equal("LastName", e.Key); + Assert.Equal("Gan/nng# T", e.Value); + }); + } + [Fact] public void CreateKeySegmentKeySegmentTemplate_ThrowsArgumentNull_EntityType() { From cae92772565777e770bcd815e38130feee9af966 Mon Sep 17 00:00:00 2001 From: Sam Xu Date: Thu, 21 Apr 2022 22:22:25 -0700 Subject: [PATCH 06/21] Issue #349: Per-request query options are not preserved with the new $batch execution Customer may retrieve the query from main request ($batch) that will create IQueryFeature into the Main HttpContext, Once created, it will cached in the main HttpContext. We should remove IQueryFeature and don't pass that to the sub request. Otherwise, the sub request query string will never be used. --- .../Batch/ODataBatchReaderExtensions.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.OData/Batch/ODataBatchReaderExtensions.cs b/src/Microsoft.AspNetCore.OData/Batch/ODataBatchReaderExtensions.cs index 0c5b507c7..fea469c5b 100644 --- a/src/Microsoft.AspNetCore.OData/Batch/ODataBatchReaderExtensions.cs +++ b/src/Microsoft.AspNetCore.OData/Batch/ODataBatchReaderExtensions.cs @@ -227,7 +227,8 @@ private static HttpContext CreateHttpContext(HttpContext originalContext) kvp.Key == typeof(IODataFeature) || kvp.Key == typeof(IItemsFeature) || kvp.Key == typeof(IHttpRequestFeature) || - kvp.Key == typeof(IHttpResponseFeature)) + kvp.Key == typeof(IHttpResponseFeature) || + kvp.Key == typeof(IQueryFeature)) // Noted: we should not pass the QueryFeature from Main request to the sub request { continue; } From 14d327cdd8889a74dbf49e451d1204aa6bc75d92 Mon Sep 17 00:00:00 2001 From: Sam Xu Date: Tue, 26 Apr 2022 22:28:14 -0700 Subject: [PATCH 07/21] issue #568: Error when function/action name contains keyword "On" (#576) * issue #568: Error when function/action name contains keyword "On" * Add the comments * Address the comments. * Address the comments. --- .../Microsoft.AspNetCore.OData.xml | 3 +- .../Conventions/OperationRoutingConvention.cs | 82 +++++++++++++------ .../FunctionRoutingConventionTests.cs | 62 +++++++++++++- 3 files changed, 120 insertions(+), 27 deletions(-) diff --git a/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml b/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml index b5aa272f8..b6c01f6a4 100644 --- a/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml +++ b/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml @@ -12427,13 +12427,14 @@ The Edm entity type. The Edm navigation source. - + Split the action based on supporting pattern. The input action name. The out of cast type name. The out of collection binding flag. + The case comparision flag. The operation name. diff --git a/src/Microsoft.AspNetCore.OData/Routing/Conventions/OperationRoutingConvention.cs b/src/Microsoft.AspNetCore.OData/Routing/Conventions/OperationRoutingConvention.cs index 4fe40cfb1..a31a81851 100644 --- a/src/Microsoft.AspNetCore.OData/Routing/Conventions/OperationRoutingConvention.cs +++ b/src/Microsoft.AspNetCore.OData/Routing/Conventions/OperationRoutingConvention.cs @@ -65,31 +65,17 @@ protected void ProcessOperations(ODataControllerActionContext context, IEdmEntit return; } - // OperationNameOnCollectionOfEntityType - string operationName = SplitActionName(actionName, out string cast, out bool isOnCollection); - + bool isOnCollection = false; IEdmEntityType castTypeFromActionName = null; - if (cast != null) - { - if (cast.Length == 0) - { - // Early return for the following cases: - // - {OperationName}On - // - {OperationName}OnCollectionOf - return; - } - castTypeFromActionName = entityType.FindTypeInInheritance(context.Model, cast, context.Options?.RouteOptions?.EnableActionNameCaseInsensitive == true) as IEdmEntityType; - if (castTypeFromActionName == null) - { - return; - } + IEdmOperation[] candidates = FindCandidates(context, actionName); + if (candidates.Length == 0) + { + // If we can't find any Edm operation using the action name directly, + // Let's split the action name and use part of it to search again. + candidates = FindCandidates(context, entityType, actionName, out castTypeFromActionName, out isOnCollection); } - // TODO: refactor here - // If we have multiple same function defined, we should match the best one? - StringComparison actionNameComparison = context.Options?.RouteOptions?.EnableActionNameCaseInsensitive == true ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal; - IEnumerable candidates = context.Model.SchemaElements.OfType().Where(f => f.IsBound && f.Name.Equals(operationName, actionNameComparison)); foreach (IEdmOperation edmOperation in candidates) { IEdmOperationParameter bindingParameter = edmOperation.Parameters.FirstOrDefault(); @@ -172,14 +158,62 @@ protected void ProcessOperations(ODataControllerActionContext context, IEdmEntit } } + private static IEdmOperation[] FindCandidates(ODataControllerActionContext context, string operationName) + { + // TODO: refactor here + // If we have multiple same function defined, we should match the best one? + + StringComparison actionNameComparison = context.Options?.RouteOptions?.EnableActionNameCaseInsensitive == true ? + StringComparison.OrdinalIgnoreCase : + StringComparison.Ordinal; + + return context.Model.SchemaElements + .OfType() + .Where(f => f.IsBound && f.Name.Equals(operationName, actionNameComparison)) + .ToArray(); + } + + private static IEdmOperation[] FindCandidates(ODataControllerActionContext context, IEdmEntityType entityType, string actionName, + out IEdmEntityType castTypeFromActionName, out bool isOnCollection) + { + // OperationNameOnCollectionOfEntityType + StringComparison caseComparision = context.Options?.RouteOptions?.EnableActionNameCaseInsensitive == true ? + StringComparison.OrdinalIgnoreCase : + StringComparison.Ordinal; + + string operationName = SplitActionName(actionName, out string cast, out isOnCollection, caseComparision); + + castTypeFromActionName = null; + if (cast != null) + { + if (cast.Length == 0) + { + // Early return for the following cases: + // - {OperationName}On + // - {OperationName}OnCollectionOf + return Array.Empty(); + } + + castTypeFromActionName = entityType.FindTypeInInheritance(context.Model, cast, context.Options?.RouteOptions?.EnableActionNameCaseInsensitive == true) as IEdmEntityType; + if (castTypeFromActionName == null) + { + return Array.Empty(); + } + } + + return FindCandidates(context, operationName); + } + /// /// Split the action based on supporting pattern. /// /// The input action name. /// The out of cast type name. /// The out of collection binding flag. + /// The case comparision flag. /// The operation name. - internal static string SplitActionName(string actionName, out string cast, out bool isOnCollection) + internal static string SplitActionName(string actionName, out string cast, out bool isOnCollection, + StringComparison comparison = StringComparison.Ordinal) { Contract.Assert(actionName != null); @@ -190,7 +224,7 @@ internal static string SplitActionName(string actionName, out string cast, out b cast = null; isOnCollection = false; string operation; - int index = actionName.IndexOf("OnCollectionOf", StringComparison.Ordinal); + int index = actionName.LastIndexOf("OnCollectionOf", comparison); if (index > 0) { operation = actionName.Substring(0, index); @@ -199,7 +233,7 @@ internal static string SplitActionName(string actionName, out string cast, out b return operation; } - index = actionName.IndexOf("On", StringComparison.Ordinal); + index = actionName.LastIndexOf("On", comparison); if (index > 0) { operation = actionName.Substring(0, index); diff --git a/test/Microsoft.AspNetCore.OData.Tests/Routing/Conventions/FunctionRoutingConventionTests.cs b/test/Microsoft.AspNetCore.OData.Tests/Routing/Conventions/FunctionRoutingConventionTests.cs index 34d95d5a9..618d11fad 100644 --- a/test/Microsoft.AspNetCore.OData.Tests/Routing/Conventions/FunctionRoutingConventionTests.cs +++ b/test/Microsoft.AspNetCore.OData.Tests/Routing/Conventions/FunctionRoutingConventionTests.cs @@ -154,11 +154,47 @@ public static TheoryDataSet FunctionRoutingConventionTes "/Customers/NS.GetWholeSalary(minSalary={minSalary},maxSalary={maxSalary},aveSalary={aveSalary})", "/Customers/GetWholeSalary(minSalary={minSalary},maxSalary={maxSalary},aveSalary={aveSalary})" } + }, + { + typeof(CustomersController), + "GetStatusOnLineOfflineUser", + new[] + { + "/Customers/NS.GetStatusOnLineOfflineUser()", + "/Customers/GetStatusOnLineOfflineUser()" + } + }, + { + typeof(CustomersController), + "GetStatusOnLineOfflineUser", + new[] + { + "/Customers/NS.GetStatusOnLineOfflineUser()", + "/Customers/GetStatusOnLineOfflineUser()" + } + }, + { + typeof(CustomersController), + "StatusLineOfflineUserOn", + new[] + { + "/Customers/NS.StatusLineOfflineUserOn()", + "/Customers/StatusLineOfflineUserOn()" + } + }, + { + typeof(CustomersController), + "GetStatusOnLineOfflineUserOnVipCustomer", + new[] + { + "/Customers/NS.VipCustomer/NS.GetStatusOnLineOfflineUser(param={param})", + "/Customers/NS.VipCustomer/GetStatusOnLineOfflineUser(param={param})" + } } }; } - } - + } + public static TheoryDataSet FunctionRoutingConventionCaseInsensitiveTestData { get @@ -448,6 +484,19 @@ private static IEdmModel GetEdmModel() getSalaray.AddOptionalParameter("aveSalary", intType, "129"); model.AddElement(getSalaray); + EdmFunction f = new EdmFunction("NS", "GetStatusOnLineOfflineUser", intType, isBound: true, entitySetPathExpression: null, isComposable: false); + f.AddParameter("entityset", new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(customer, false)))); + model.AddElement(f); + + EdmFunction f2 = new EdmFunction("NS", "StatusLineOfflineUserOn", intType, isBound: true, entitySetPathExpression: null, isComposable: false); + f2.AddParameter("entityset", new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(customer, false)))); + model.AddElement(f2); + + EdmFunction f3 = new EdmFunction("NS", "GetStatusOnLineOfflineUser", intType, isBound: true, entitySetPathExpression: null, isComposable: false); + f3.AddParameter("entityset", new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(vipCustomer, false)))); + f3.AddParameter("param", intType); + model.AddElement(f3); + EdmEntityContainer container = new EdmEntityContainer("NS", "Default"); container.AddEntitySet("Customers", customer); container.AddEntitySet("CustomersCaseInsensitive", customer); @@ -461,6 +510,15 @@ private class CustomersController public void Get() { } + [HttpGet] + public void GetStatusOnLineOfflineUser() { } + + [HttpGet] + public void GetStatusOnLineOfflineUserOnVipCustomer(int param) { } + + [HttpGet] + public void StatusLineOfflineUserOn() { } + [HttpGet] public void IsBaseUpgraded(int key, CancellationToken cancellation) { } From eea3a95a4831432d08fcdd5beaea0ec791d642ce Mon Sep 17 00:00:00 2001 From: Sam Xu Date: Tue, 26 Apr 2022 22:36:49 -0700 Subject: [PATCH 08/21] Update the release version to 8.0.10 --- tool/builder.versions.settings.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tool/builder.versions.settings.targets b/tool/builder.versions.settings.targets index 834768080..c89f49cb0 100644 --- a/tool/builder.versions.settings.targets +++ b/tool/builder.versions.settings.targets @@ -3,7 +3,7 @@ 8 0 - 9 + 10 From 3b0b4a2f3a5ae946b5c080dddc831b0dfeb230b9 Mon Sep 17 00:00:00 2001 From: John Gathogo Date: Wed, 27 Apr 2022 12:22:34 +0300 Subject: [PATCH 09/21] Support FromBody parameters with actions and functions --- .../Formatter/ODataOutputFormatterHelper.cs | 26 +------------ .../Routing/Template/ActionSegmentTemplate.cs | 11 +++++- .../Template/FunctionSegmentTemplate.cs | 11 +++++- .../Template/SegmentTemplateHelpers.cs | 21 ++++++++++ .../Serialization/ComplexTypeTests.cs | 4 ++ .../Template/ActionSegmentTemplateTests.cs | 38 +++++++++++++++++++ .../Template/FunctionSegmentTemplateTests.cs | 36 ++++++++++++++++++ 7 files changed, 119 insertions(+), 28 deletions(-) diff --git a/src/Microsoft.AspNetCore.OData/Formatter/ODataOutputFormatterHelper.cs b/src/Microsoft.AspNetCore.OData/Formatter/ODataOutputFormatterHelper.cs index 351158d9f..57d28ab60 100644 --- a/src/Microsoft.AspNetCore.OData/Formatter/ODataOutputFormatterHelper.cs +++ b/src/Microsoft.AspNetCore.OData/Formatter/ODataOutputFormatterHelper.cs @@ -66,7 +66,7 @@ internal static async Task WriteToStreamAsync( IODataSerializer serializer = GetSerializer(type, value, request, serializerProvider); ODataPath path = request.ODataFeature().Path; - IEdmNavigationSource targetNavigationSource = GetTargetNavigationSource(path, model); + IEdmNavigationSource targetNavigationSource = path.GetNavigationSource(); HttpResponse response = request.HttpContext.Response; // serialize a response @@ -196,30 +196,6 @@ internal static IODataSerializer GetSerializer(Type type, object value, HttpRequ return serializer; } - private static IEdmNavigationSource GetTargetNavigationSource(ODataPath path, IEdmModel model) - { - if (path == null) - { - return null; - } - - Contract.Assert(model != null); - - OperationSegment operationSegment = path.LastSegment as OperationSegment; - if (operationSegment != null) - { - // OData model builder uses an annotation to save the function returned entity set. - // TODO: we need to refactor it later. - ReturnedEntitySetAnnotation entitySetAnnotation = model.GetAnnotationValue(operationSegment.Operations.Single()); - if (entitySetAnnotation != null) - { - return model.EntityContainer.FindEntitySet(entitySetAnnotation.EntitySetName); - } - } - - return path.GetNavigationSource(); - } - private static string GetRootElementName(ODataPath path) { if (path != null) diff --git a/src/Microsoft.AspNetCore.OData/Routing/Template/ActionSegmentTemplate.cs b/src/Microsoft.AspNetCore.OData/Routing/Template/ActionSegmentTemplate.cs index c339c79f1..0329c8cf5 100644 --- a/src/Microsoft.AspNetCore.OData/Routing/Template/ActionSegmentTemplate.cs +++ b/src/Microsoft.AspNetCore.OData/Routing/Template/ActionSegmentTemplate.cs @@ -10,6 +10,7 @@ using System.Linq; using Microsoft.OData; using Microsoft.OData.Edm; +using Microsoft.OData.ModelBuilder; using Microsoft.OData.UriParser; namespace Microsoft.AspNetCore.OData.Routing.Template @@ -104,7 +105,15 @@ public override bool TryTranslate(ODataTemplateTranslateContext context) throw Error.ArgumentNull(nameof(context)); } - context.Segments.Add(Segment); + if (NavigationSource != null) + { + context.Segments.Add(Segment); + return true; + } + + IEdmNavigationSource navigationSource = SegmentTemplateHelpers.GetNavigationSourceFromEdmOperation(context.Model, Action); + OperationSegment actionSegment = new OperationSegment(Action, navigationSource as IEdmEntitySetBase); + context.Segments.Add(actionSegment); return true; } } diff --git a/src/Microsoft.AspNetCore.OData/Routing/Template/FunctionSegmentTemplate.cs b/src/Microsoft.AspNetCore.OData/Routing/Template/FunctionSegmentTemplate.cs index 0afe7ccd2..ea1a676a3 100644 --- a/src/Microsoft.AspNetCore.OData/Routing/Template/FunctionSegmentTemplate.cs +++ b/src/Microsoft.AspNetCore.OData/Routing/Template/FunctionSegmentTemplate.cs @@ -11,6 +11,7 @@ using Microsoft.AspNetCore.OData.Edm; using Microsoft.OData; using Microsoft.OData.Edm; +using Microsoft.OData.ModelBuilder; using Microsoft.OData.UriParser; namespace Microsoft.AspNetCore.OData.Routing.Template @@ -144,10 +145,16 @@ public override bool TryTranslate(ODataTemplateTranslateContext context) throw Error.ArgumentNull(nameof(context)); } + IEdmNavigationSource navigationSource = NavigationSource; + if (navigationSource == null) + { + navigationSource = SegmentTemplateHelpers.GetNavigationSourceFromEdmOperation(context.Model, Function); + } + // If the function has no parameter, we don't need to do anything and just return an operation segment. if (ParameterMappings.Count == 0) { - context.Segments.Add(new OperationSegment(Function, NavigationSource as IEdmEntitySetBase)); + context.Segments.Add(new OperationSegment(Function, navigationSource as IEdmEntitySetBase)); return true; } @@ -172,7 +179,7 @@ public override bool TryTranslate(ODataTemplateTranslateContext context) return false; } - context.Segments.Add(new OperationSegment(Function, parameters, NavigationSource as IEdmEntitySetBase)); + context.Segments.Add(new OperationSegment(Function, parameters, navigationSource as IEdmEntitySetBase)); return true; } diff --git a/src/Microsoft.AspNetCore.OData/Routing/Template/SegmentTemplateHelpers.cs b/src/Microsoft.AspNetCore.OData/Routing/Template/SegmentTemplateHelpers.cs index 46e44a38f..8535398aa 100644 --- a/src/Microsoft.AspNetCore.OData/Routing/Template/SegmentTemplateHelpers.cs +++ b/src/Microsoft.AspNetCore.OData/Routing/Template/SegmentTemplateHelpers.cs @@ -15,6 +15,7 @@ using Microsoft.AspNetCore.Routing; using Microsoft.OData; using Microsoft.OData.Edm; +using Microsoft.OData.ModelBuilder; using Microsoft.OData.UriParser; namespace Microsoft.AspNetCore.OData.Routing.Template @@ -173,5 +174,25 @@ internal static bool IsMatchParameters(RouteValueDictionary routeValues, IDictio // 3) now the parsedKeyValues (p1, p3) is not equal to actualParameters (p1, p2, p3) return parameterMappings.Count == parsedKeyValues.Count; } + + /// + /// Gets the navigation source from an Edm operation. + /// + /// The Edm model. + /// The Edm operation. + /// + /// The navigation source or null if the annotation indicating the mapping from an Edm operation to an entity set is not found. + /// + internal static IEdmNavigationSource GetNavigationSourceFromEdmOperation(IEdmModel model, IEdmOperation operation) + { + ReturnedEntitySetAnnotation entitySetAnnotation = model?.GetAnnotationValue(operation); + + if (entitySetAnnotation != null) + { + return model.EntityContainer.FindEntitySet(entitySetAnnotation.EntitySetName); + } + + return null; + } } } diff --git a/test/Microsoft.AspNetCore.OData.Tests/Formatter/Serialization/ComplexTypeTests.cs b/test/Microsoft.AspNetCore.OData.Tests/Formatter/Serialization/ComplexTypeTests.cs index 52dbe205b..2367b2652 100644 --- a/test/Microsoft.AspNetCore.OData.Tests/Formatter/Serialization/ComplexTypeTests.cs +++ b/test/Microsoft.AspNetCore.OData.Tests/Formatter/Serialization/ComplexTypeTests.cs @@ -5,6 +5,7 @@ // //------------------------------------------------------------------------------ +using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.OData.Extensions; using Microsoft.AspNetCore.OData.Formatter.MediaType; @@ -13,6 +14,7 @@ using Microsoft.OData; using Microsoft.OData.Edm; using Microsoft.OData.ModelBuilder; +using Microsoft.OData.UriParser; using Xunit; namespace Microsoft.AspNetCore.OData.Tests.Formatter.Serialization @@ -26,6 +28,8 @@ public async Task ComplexTypeSerializesAsOData() string routeName = "OData"; IEdmModel model = GetSampleModel(); var request = RequestFactory.Create("Get", "http://localhost/property", opt => opt.AddRouteComponents(routeName, model)); + var addressComplexType = model.SchemaElements.OfType().Single(d => d.Name.Equals("Address")); + request.ODataFeature().Path = new ODataPath(new ValueSegment(addressComplexType)); request.ODataFeature().Model = model; request.ODataFeature().RoutePrefix = routeName; diff --git a/test/Microsoft.AspNetCore.OData.Tests/Routing/Template/ActionSegmentTemplateTests.cs b/test/Microsoft.AspNetCore.OData.Tests/Routing/Template/ActionSegmentTemplateTests.cs index c3f73a0c8..4556e5338 100644 --- a/test/Microsoft.AspNetCore.OData.Tests/Routing/Template/ActionSegmentTemplateTests.cs +++ b/test/Microsoft.AspNetCore.OData.Tests/Routing/Template/ActionSegmentTemplateTests.cs @@ -8,12 +8,17 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.OData.Routing; using Microsoft.AspNetCore.OData.Routing.Template; using Microsoft.AspNetCore.OData.Tests.Commons; +using Microsoft.AspNetCore.Routing; using Microsoft.OData; using Microsoft.OData.Edm; +using Microsoft.OData.ModelBuilder; using Microsoft.OData.UriParser; +using Moq; using Xunit; namespace Microsoft.AspNetCore.OData.Tests.Routing.Template @@ -142,5 +147,38 @@ public void TryTranslateActionSegmentTemplate_ReturnsODataActionImportSegment() OperationSegment actionSegment = Assert.IsType(actual); Assert.Same(action, actionSegment.Operations.First()); } + + [Fact] + public void TryTranslateActionSegmentTemplate_ReturnsODataActionSegment_WithReturnedEntitySet() + { + // Arrange + var httpContext = new Mock().Object; + var endpoint = new Endpoint(c => Task.CompletedTask, EndpointMetadataCollection.Empty, "Test"); + var routeValues = new RouteValueDictionary(); + + var model = new EdmModel(); + var entityType = new EdmEntityType("NS", "Entity"); + entityType.AddKeys(entityType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32)); + model.AddElement(entityType); + EdmAction action = new EdmAction("NS", "Action", new EdmEntityTypeReference(entityType, true), true, null); + model.AddElement(action); + var entityContainer = new EdmEntityContainer("NS", "Default"); + var entitySet = entityContainer.AddEntitySet("EntitySet", entityType); + model.AddElement(entityContainer); + model.SetAnnotationValue(action, new ReturnedEntitySetAnnotation("EntitySet")); + + var template = new ActionSegmentTemplate(action, null); + var translateContext = new ODataTemplateTranslateContext(httpContext, endpoint, routeValues, model); + + // Act + bool ok = template.TryTranslate(translateContext); + + // Assert + Assert.True(ok); + var actual = Assert.Single(translateContext.Segments); + var actionSegment = Assert.IsType(actual); + Assert.Equal(actionSegment.EdmType, entityType); + Assert.Equal(actionSegment.EntitySet, entitySet); + } } } diff --git a/test/Microsoft.AspNetCore.OData.Tests/Routing/Template/FunctionSegmentTemplateTests.cs b/test/Microsoft.AspNetCore.OData.Tests/Routing/Template/FunctionSegmentTemplateTests.cs index 3c18a2019..399bc6910 100644 --- a/test/Microsoft.AspNetCore.OData.Tests/Routing/Template/FunctionSegmentTemplateTests.cs +++ b/test/Microsoft.AspNetCore.OData.Tests/Routing/Template/FunctionSegmentTemplateTests.cs @@ -8,12 +8,15 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.OData.Routing; using Microsoft.AspNetCore.OData.Routing.Template; using Microsoft.AspNetCore.OData.Tests.Commons; using Microsoft.AspNetCore.Routing; using Microsoft.OData; using Microsoft.OData.Edm; +using Microsoft.OData.ModelBuilder; using Microsoft.OData.UriParser; using Moq; using Xunit; @@ -404,5 +407,38 @@ public void TryTranslateFunctionSegmentTemplate_ReturnsODataFunctionSegment_Usin Assert.Equal("name", parameter.Name); Assert.Equal("Ji/Change# T", parameter.Value.ToString()); } + + [Fact] + public void TryTranslateFunctionSegmentTemplate_ReturnsODataFunctionSegment_WithReturnedEntitySet() + { + // Arrange + var httpContext = new Mock().Object; + var endpoint = new Endpoint(c => Task.CompletedTask, EndpointMetadataCollection.Empty, "Test"); + var routeValues = new RouteValueDictionary(); + + var model = new EdmModel(); + var entityType = new EdmEntityType("NS", "Entity"); + entityType.AddKeys(entityType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32)); + model.AddElement(entityType); + EdmFunction function = new EdmFunction("NS", "Function", new EdmEntityTypeReference(entityType, true), true, null, true); + model.AddElement(function); + var entityContainer = new EdmEntityContainer("NS", "Default"); + var entitySet = entityContainer.AddEntitySet("EntitySet", entityType); + model.AddElement(entityContainer); + model.SetAnnotationValue(function, new ReturnedEntitySetAnnotation("EntitySet")); + + var template = new FunctionSegmentTemplate(function, null); + var translateContext = new ODataTemplateTranslateContext(httpContext, endpoint, routeValues, model); + + // Act + bool ok = template.TryTranslate(translateContext); + + // Assert + Assert.True(ok); + var actual = Assert.Single(translateContext.Segments); + var functionSegment = Assert.IsType(actual); + Assert.Equal(functionSegment.EdmType, entityType); + Assert.Equal(functionSegment.EntitySet, entitySet); + } } } From 3df3a0b009ed465a9e0a87d0c722d08921d6b4c4 Mon Sep 17 00:00:00 2001 From: Sam Xu Date: Tue, 3 May 2022 11:30:27 -0700 Subject: [PATCH 10/21] Fix issue #587: AddODataNewtonsoftJson should call AddODataNewtonsoftJson with null --- ...ODataNewtonsoftJsonMvcBuilderExtensions.cs | 2 +- .../Microsoft.AspNetCore.OData.xml | 10 +++ ...NewtonsoftJsonMvcBuilderExtensionsTests.cs | 74 +++++++++++++++++++ 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 test/Microsoft.AspNetCore.OData.NewtonsoftJson.Tests/ODataNewtonsoftJsonMvcBuilderExtensionsTests.cs diff --git a/src/Microsoft.AspNetCore.OData.NewtonsoftJson/ODataNewtonsoftJsonMvcBuilderExtensions.cs b/src/Microsoft.AspNetCore.OData.NewtonsoftJson/ODataNewtonsoftJsonMvcBuilderExtensions.cs index e6810bb06..fee0eb930 100644 --- a/src/Microsoft.AspNetCore.OData.NewtonsoftJson/ODataNewtonsoftJsonMvcBuilderExtensions.cs +++ b/src/Microsoft.AspNetCore.OData.NewtonsoftJson/ODataNewtonsoftJsonMvcBuilderExtensions.cs @@ -55,7 +55,7 @@ public static IMvcBuilder AddODataNewtonsoftJson(this IMvcBuilder builder, /// The . public static IMvcCoreBuilder AddODataNewtonsoftJson(this IMvcCoreBuilder builder) { - return builder.AddNewtonsoftJson(null); + return builder.AddODataNewtonsoftJson(null); } /// diff --git a/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml b/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml index b6c01f6a4..2ea93aae3 100644 --- a/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml +++ b/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml @@ -14056,6 +14056,16 @@ The parameter mappings. True/False. + + + Gets the navigation source from an Edm operation. + + The Edm model. + The Edm operation. + + The navigation source or null if the annotation indicating the mapping from an Edm operation to an entity set is not found. + + Represents a template that could match an . diff --git a/test/Microsoft.AspNetCore.OData.NewtonsoftJson.Tests/ODataNewtonsoftJsonMvcBuilderExtensionsTests.cs b/test/Microsoft.AspNetCore.OData.NewtonsoftJson.Tests/ODataNewtonsoftJsonMvcBuilderExtensionsTests.cs new file mode 100644 index 000000000..e9342c505 --- /dev/null +++ b/test/Microsoft.AspNetCore.OData.NewtonsoftJson.Tests/ODataNewtonsoftJsonMvcBuilderExtensionsTests.cs @@ -0,0 +1,74 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) .NET Foundation and Contributors. All rights reserved. +// See License.txt in the project root for license information. +// +//------------------------------------------------------------------------------ + +using System; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.ApplicationParts; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Xunit; + +namespace Microsoft.AspNetCore.OData.NewtonsoftJson.Tests +{ + public class ODataNewtonsoftJsonMvcBuilderExtensionsTests + { + [Fact] + public void AddODataNewtonsoftJson_OnIMvcBuilder_Throws_NullBuilder() + { + // Arrange + IMvcBuilder builder = null; + + // Act & Assert + Assert.Throws("builder", () => builder.AddODataNewtonsoftJson()); + } + + [Fact] + public void AddODataNewtonsoftJson_OnIMvcCoreBuilder_Throws_NullBuilder() + { + // Arrange + IMvcCoreBuilder builder = null; + + // Act & Assert + Assert.Throws("builder", () => builder.AddODataNewtonsoftJson()); + } + + [Fact] + public void AddODataNewtonsoftJson_OnMvcCoreBuilder_RegistersODataJsonConverts() + { + // Arrange + var services = new ServiceCollection(); + services.AddLogging(); + IMvcCoreBuilder builder = new MyMvcCoreBuilder + { + Services = services + }; + + // Act + builder.AddODataNewtonsoftJson(); + IServiceProvider provider = services.BuildServiceProvider(); + + // Assert + IOptions options = provider.GetService>(); + Assert.NotNull(options); + + MvcNewtonsoftJsonOptions jsonOptions = options.Value; + Assert.Contains(jsonOptions.SerializerSettings.Converters, c => c is JSelectExpandWrapperConverter); + Assert.Contains(jsonOptions.SerializerSettings.Converters, c => c is JDynamicTypeWrapperConverter); + Assert.Contains(jsonOptions.SerializerSettings.Converters, c => c is JPageResultValueConverter); + Assert.Contains(jsonOptions.SerializerSettings.Converters, c => c is JSingleResultValueConverter); + } + } + + internal class MyMvcCoreBuilder : IMvcCoreBuilder + { + /// + public ApplicationPartManager PartManager { get; set; } + + /// + public IServiceCollection Services { get; set; } + } +} From e03e5e76e89e114280929bef303b794b86b4f291 Mon Sep 17 00:00:00 2001 From: Sam Xu Date: Wed, 11 May 2022 15:51:09 -0700 Subject: [PATCH 11/21] Set Order for composite keys 1) use ColumnAttribute in conventional model builder 2) set Order value in non-conventional model builder --- sample/ODataRoutingSample/Models/EdmModelBuilder.cs | 4 ++++ sample/ODataRoutingSample/Models/Person.cs | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/sample/ODataRoutingSample/Models/EdmModelBuilder.cs b/sample/ODataRoutingSample/Models/EdmModelBuilder.cs index 7ed3df493..ac25cbd8c 100644 --- a/sample/ODataRoutingSample/Models/EdmModelBuilder.cs +++ b/sample/ODataRoutingSample/Models/EdmModelBuilder.cs @@ -18,6 +18,10 @@ public static IEdmModel GetEdmModel() builder.EntitySet("Products"); builder.EntitySet("People").EntityType.HasKey(c => new { c.FirstName, c.LastName }); + // use the following codes to set the order and change the route template. + // builder.EntityType().Property(c => c.FirstName).Order = 2; + // builder.EntityType().Property(c => c.LastName).Order = 1; + // function with optional parameters var functionWithOptional = builder.EntityType().Collection.Function("GetWholeSalary").ReturnsCollectionFromEntitySet("Orders"); functionWithOptional.Parameter("minSalary"); diff --git a/sample/ODataRoutingSample/Models/Person.cs b/sample/ODataRoutingSample/Models/Person.cs index d06446880..658344c3d 100644 --- a/sample/ODataRoutingSample/Models/Person.cs +++ b/sample/ODataRoutingSample/Models/Person.cs @@ -5,12 +5,17 @@ // //------------------------------------------------------------------------------ +using System.ComponentModel.DataAnnotations.Schema; + namespace ODataRoutingSample.Models { public class Person { + // [Column(Order = 1)] // This attribute can be used with [Key] convention model building + // It is ignored if the property is added explicitly. public string FirstName { get; set; } + // [Column(Order = 2)] public string LastName { get; set; } } } From 4653b4a521ab48f8b95484b9bbf47f5e8ff11ea6 Mon Sep 17 00:00:00 2001 From: aldrashan Date: Tue, 17 May 2022 13:35:49 +0200 Subject: [PATCH 12/21] Update README.md Typo's --- README.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f1caaf752..7a2fbeae9 100644 --- a/README.md +++ b/README.md @@ -87,9 +87,7 @@ That's it. ### 3.1 Building and Testing in Visual Studio -~~Visual Studio 2019 Preview is necessary to build the project.~~ - -Since the project introducts the .NET 6 targe framework to support `DateOnly` and `TimeOnly`, Visual Studio 2022 is required to build source project. (Edit at 2/10/2022) +Visual Studio 2022 is required to build the source project in order to support the `DateOnly` and `TimeOnly` types, which were introduced in .NET 6. ### 3.2 One-click build and test script in command line Coming soon. @@ -98,11 +96,11 @@ Coming soon. The symbol package is uploaded to nuget symbol server. -It supports source link debug. Remember to make `Enable Source Link support` checked if you debug using Visual Studio. +It supports source link debug. Remember to check `Enable Source Link support` if you debug using Visual Studio. ### 3.4 Nightly Builds -The nightly build process will upload a NuGet packages for ASP.NET Core OData to: +The nightly build process will upload NuGet packages for ASP.NET Core OData to: * https://www.myget.org/gallery/webapinetcore @@ -124,7 +122,7 @@ To connect to webapinightly feed, use this feed URL: ### 5.1 Contribution -Any contribution, feature request, bug, issue are welcome. +Any contributions, feature requests, bugs and issues are welcome. ### 5.2 Support From 9225d1eba1601bf1470b7e611cdd595fa479dbfc Mon Sep 17 00:00:00 2001 From: Nthemba Date: Thu, 9 Jun 2022 10:32:39 +0300 Subject: [PATCH 13/21] Fixed Select Wilcard on Action and Function (#594) * Fixed Select Wilcard on Action and Function * Added spacing between tests Co-authored-by: John Gathogo * Update test/Microsoft.AspNetCore.OData.Tests/Query/ODataQueryContextTests.cs Co-authored-by: John Gathogo * Update test/Microsoft.AspNetCore.OData.Tests/Query/ODataQueryContextTests.cs Co-authored-by: John Gathogo * Added e2e test on select * on Function * Update test/Microsoft.AspNetCore.OData.E2E.Tests/Query/SelectWilCardOnFunction/SelectWildCardOnFunctionTests.cs Co-authored-by: John Gathogo * Update test/Microsoft.AspNetCore.OData.E2E.Tests/Query/SelectWilCardOnFunction/SelectWildCardOnFunctionTests.cs Co-authored-by: John Gathogo * Apply suggestions from code review Co-authored-by: John Gathogo * Apply suggestions from code review Co-authored-by: John Gathogo * Moved EDMModel to startup class * Update test/Microsoft.AspNetCore.OData.Tests/Query/ODataQueryContextTests.cs Co-authored-by: Kennedy Kang'ethe * Update test/Microsoft.AspNetCore.OData.E2E.Tests/Query/SelectWilCardOnFunction/SelectWildCardOnFunctionTests.cs Co-authored-by: John Gathogo * Update test/Microsoft.AspNetCore.OData.E2E.Tests/Query/SelectWilCardOnFunction/SelectWildCardOnFunctionTests.cs Removed redundant null assertions Co-authored-by: John Gathogo * Update test/Microsoft.AspNetCore.OData.E2E.Tests/Query/SelectWilCardOnFunction/SelectWildCardOnFunctionTests.cs Co-authored-by: Garrett DeBruin * Update test/Microsoft.AspNetCore.OData.E2E.Tests/Query/SelectWilCardOnFunction/SelectWildCardOnFunctionTests.cs Co-authored-by: Garrett DeBruin * Update test/Microsoft.AspNetCore.OData.E2E.Tests/Query/SelectWilCardOnFunction/SelectWildCardOnFunctionTests.cs Co-authored-by: Garrett DeBruin * Update test/Microsoft.AspNetCore.OData.E2E.Tests/Query/SelectWilCardOnFunction/SelectWildCardOnFunctionTests.cs Co-authored-by: Kennedy Kang'ethe * Update test/Microsoft.AspNetCore.OData.E2E.Tests/Query/SelectWilCardOnFunction/SelectWildCardOnFunctionTests.cs Co-authored-by: Kennedy Kang'ethe Co-authored-by: June Ngei Co-authored-by: John Gathogo Co-authored-by: Kennedy Kang'ethe Co-authored-by: Garrett DeBruin --- .../Routing/ODataPathExtensions.cs | 2 +- .../SelectWildCardOnFunctionTests.cs | 113 ++++++++++++++++++ .../Query/ODataQueryContextTests.cs | 36 ++++++ 3 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 test/Microsoft.AspNetCore.OData.E2E.Tests/Query/SelectWilCardOnFunction/SelectWildCardOnFunctionTests.cs diff --git a/src/Microsoft.AspNetCore.OData/Routing/ODataPathExtensions.cs b/src/Microsoft.AspNetCore.OData/Routing/ODataPathExtensions.cs index a793641af..04a871050 100644 --- a/src/Microsoft.AspNetCore.OData/Routing/ODataPathExtensions.cs +++ b/src/Microsoft.AspNetCore.OData/Routing/ODataPathExtensions.cs @@ -158,7 +158,7 @@ internal static (IEdmProperty, IEdmStructuredType, string) GetPropertyAndStructu { if (structuredType == null) { - structuredType = operationSegment.EdmType as IEdmStructuredType; + structuredType = operationSegment.EdmType.AsElementType() as IEdmStructuredType; } string name = operationSegment.Operations.First().FullName() + typeCast; diff --git a/test/Microsoft.AspNetCore.OData.E2E.Tests/Query/SelectWilCardOnFunction/SelectWildCardOnFunctionTests.cs b/test/Microsoft.AspNetCore.OData.E2E.Tests/Query/SelectWilCardOnFunction/SelectWildCardOnFunctionTests.cs new file mode 100644 index 000000000..be96323ca --- /dev/null +++ b/test/Microsoft.AspNetCore.OData.E2E.Tests/Query/SelectWilCardOnFunction/SelectWildCardOnFunctionTests.cs @@ -0,0 +1,113 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) .NET Foundation and Contributors. All rights reserved. +// See License.txt in the project root for license information. +// +//------------------------------------------------------------------------------ + +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.OData.Query; +using Microsoft.AspNetCore.OData.Routing.Controllers; +using Microsoft.AspNetCore.OData.TestCommon; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.OData.Edm; +using Microsoft.OData.ModelBuilder; +using Newtonsoft.Json.Linq; +using System.Collections.Generic; +using System.Net; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading.Tasks; +using Xunit; + +namespace Microsoft.AspNetCore.OData.E2E.Tests.Query.SelectWilCardOnFunction +{ + public sealed class SelectWildCardOnFunctionTests : WebODataTestBase + { + public class Startup : TestStartupBase + { + public override void ConfigureServices(IServiceCollection services) + { + services.ConfigureControllers(typeof(CustomersController)); + + IEdmModel model = GetEdmModel(); + services.AddControllers().AddOData(opt => + { + opt.Select(); + opt.RouteOptions.EnableNonParenthesisForEmptyParameterFunction = true; + opt.AddRouteComponents("odata", model); + }); + } + + public static IEdmModel GetEdmModel() + { + ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); + builder.EntitySet("Customers").EntityType + .Collection.Function("GetAllCustomers") + .ReturnsCollectionFromEntitySet("Customers"); + + return builder.GetEdmModel(); + } + } + + public SelectWildCardOnFunctionTests(WebODataTestFixture fixture) + : base(fixture) + { + } + + /// + /// For Select query with wildcard on Function + /// + /// + [Fact] + public async Task SelectWildCardOnFunction_Success() + { + //Arrange + string queryUrl = "odata/Customers/GetAllCustomers?$select=*"; + + using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, queryUrl)) + { + request.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json;odata.metadata=none")); + + //Act + using (HttpResponseMessage response = await this.Client.SendAsync(request)) + { + // Assert + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + + List customers = JToken.Parse(await response.Content.ReadAsStringAsync())["value"].ToObject>(); + foreach(Customer c in customers) + { + Assert.Equal("custId1", c.Id); + Assert.Equal("John", c.Name); + Assert.Equal("Active", c.Status); + } + } + } + } + } + + public class Customer + { + public string Id { get; set; } + public string Name { get; set; } + public string Status { get; set; } + } + + public class CustomersController : ODataController + { + [HttpGet] + public IEnumerable GetAllCustomers() + { + return new List() + { + new Customer + { + Id = "custId1", + Name = "John", + Status = "Active" + } + }; + } + } +} diff --git a/test/Microsoft.AspNetCore.OData.Tests/Query/ODataQueryContextTests.cs b/test/Microsoft.AspNetCore.OData.Tests/Query/ODataQueryContextTests.cs index 67656bee5..83a8c6c4d 100644 --- a/test/Microsoft.AspNetCore.OData.Tests/Query/ODataQueryContextTests.cs +++ b/test/Microsoft.AspNetCore.OData.Tests/Query/ODataQueryContextTests.cs @@ -6,6 +6,8 @@ //------------------------------------------------------------------------------ using System; +using System.Collections; +using System.Collections.Generic; using Microsoft.AspNetCore.OData.Query; using Microsoft.AspNetCore.OData.Tests.Commons; using Microsoft.AspNetCore.OData.Tests.Models; @@ -91,6 +93,40 @@ public void CtorODataQueryContext_TakingClrTypeAndPath_SetsProperties() Assert.Same(typeof(Customer), context.ElementClrType); } + [Fact] + public void CtorODataQueryContext_TakingOperationAndPath_SetsProperties() + { + // Arrange + ODataModelBuilder odataModel = new ODataModelBuilder().Add_Customer_EntityType(); + string setName = typeof(Customer).Name; + odataModel.EntitySet(setName); + odataModel.EntitySet("Customers").EntityType + .Collection.Function("GetAllCustomers") + .ReturnsCollectionFromEntitySet("GetAllCustomer"); + IEdmModel model = odataModel.GetEdmModel(); + IEnumerable operationConfiguration = odataModel.Operations; + + string qualifiedName = null; + foreach(var op in operationConfiguration) + { + qualifiedName = op.FullyQualifiedName; + } + + IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet(setName); + IEdmEntityType entityType = entitySet.EntityType(); + IEnumerable operations = model.FindDeclaredOperations(qualifiedName); + + ODataPath path = new ODataPath(new EntitySetSegment(entitySet), new OperationSegment(operations, entitySet)); + + // Act + ODataQueryContext context = new ODataQueryContext(model, typeof(Customer), path); + + // Assert + Assert.Same(model, context.Model); + Assert.Same(entityType, context.TargetStructuredType); + Assert.Same(typeof(Customer), context.ElementClrType); + } + [Fact] public void CtorODataQueryContext_TakingEdmType_ThrowsArgumentNull_Model() { From c4f229dc74fcfb738587c807a69faef11a54d15d Mon Sep 17 00:00:00 2001 From: Kennedy Kang'ethe Date: Mon, 4 Jul 2022 15:09:54 +0300 Subject: [PATCH 14/21] Create ODataError for non-success responses (#623) --- .../Common/Error.cs | 8 + .../Microsoft.AspNetCore.OData.xml | 252 ++ .../PublicAPI.Unshipped.txt | 44 + .../Results/BadRequestODataResult.cs | 74 + .../Results/ConflictODataResult.cs | 74 + .../Results/IODataErrorResult.cs | 24 + .../Results/NotFoundODataResult.cs | 74 + .../Results/ODataErrorResult.cs | 77 + .../Results/UnauthorizedODataResult.cs | 74 + .../UnprocessableEntityODataResult .cs | 74 + .../Routing/Controllers/ODataController.cs | 122 + .../ODataErrors/ODataErrorsController.cs | 115 + .../ODataErrors/ODataErrorsDataModel.cs | 27 + .../ODataErrors/ODataErrorsEdmModel.cs | 24 + .../ODataErrors/ODataErrorsTests.cs | 198 + .../Microsoft.AspNetCore.OData.Tests.csproj | 2 + ...rosoft.AspNetCore.OData.PublicApi.Net5.bsl | 88 + ...rosoft.AspNetCore.OData.PublicApi.Net6.bsl | 3360 +++++++++++++++++ ...t.AspNetCore.OData.PublicApi.NetCore31.bsl | 88 + .../PublicApi/PublicApiTest.cs | 2 + .../Query/ODataLevelTests.cs | 15 +- 21 files changed, 4811 insertions(+), 5 deletions(-) create mode 100644 src/Microsoft.AspNetCore.OData/Results/BadRequestODataResult.cs create mode 100644 src/Microsoft.AspNetCore.OData/Results/ConflictODataResult.cs create mode 100644 src/Microsoft.AspNetCore.OData/Results/IODataErrorResult.cs create mode 100644 src/Microsoft.AspNetCore.OData/Results/NotFoundODataResult.cs create mode 100644 src/Microsoft.AspNetCore.OData/Results/ODataErrorResult.cs create mode 100644 src/Microsoft.AspNetCore.OData/Results/UnauthorizedODataResult.cs create mode 100644 src/Microsoft.AspNetCore.OData/Results/UnprocessableEntityODataResult .cs create mode 100644 test/Microsoft.AspNetCore.OData.E2E.Tests/ODataErrors/ODataErrorsController.cs create mode 100644 test/Microsoft.AspNetCore.OData.E2E.Tests/ODataErrors/ODataErrorsDataModel.cs create mode 100644 test/Microsoft.AspNetCore.OData.E2E.Tests/ODataErrors/ODataErrorsEdmModel.cs create mode 100644 test/Microsoft.AspNetCore.OData.E2E.Tests/ODataErrors/ODataErrorsTests.cs create mode 100644 test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net6.bsl diff --git a/src/Microsoft.AspNetCore.OData/Common/Error.cs b/src/Microsoft.AspNetCore.OData/Common/Error.cs index 1caff0eaa..e6045525e 100644 --- a/src/Microsoft.AspNetCore.OData/Common/Error.cs +++ b/src/Microsoft.AspNetCore.OData/Common/Error.cs @@ -229,5 +229,13 @@ internal static NotSupportedException NotSupported(string messageFormat, params { return new NotSupportedException(Error.Format(messageFormat, messageArgs)); } + + internal static void ValidateErrorCode(string expectedErrorCode, Microsoft.OData.ODataError error) + { + if (expectedErrorCode != error.ErrorCode) + { + throw Argument(error.ErrorCode, "Invalid error code"); + } + } } } diff --git a/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml b/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml index 2ea93aae3..8bbf63e82 100644 --- a/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml +++ b/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml @@ -11841,6 +11841,58 @@ Gets or sets the instance of the element being selected and expanded. + + + Represents a result that when executed will produce a Bad Request (400) response. + + This result creates an with status code: 400. + + + + OData error. + + + + + Initializes a new instance of the class. + + Error message. + + + + Initializes a new instance of the class. + + An object. + + + + + + + Represents a result that when executed will produce a Conflict (409) response. + + This result creates an with status code: 409. + + + + OData error. + + + + + Initializes a new instance of the class. + + Error message. + + + + Initializes a new instance of the class. + + An object. + + + + Represents an action result that is a response to a create operation that adds an entity to an entity set. @@ -11864,6 +11916,69 @@ + + + Provide the interface for the details of a given OData error result. + + + + + OData error. + + + + + Represents a result that when executed will produce a Not Found (404) response. + + This result creates an with status code: 404. + + + + OData error. + + + + + Initializes a new instance of the class. + + Error message. + + + + Initializes a new instance of the class. + + An object. + + + + + + + Represents a result that when executed will produce an . + + This result creates an response. + + + + OData error. + + + + + Initializes a new instance of the class. + + Error code. + Error message. + + + + Initializes a new instance of the class. + + An object. + + + + Represents a feed of entities that includes additional information that OData formats support. @@ -12010,6 +12125,58 @@ The serialization options to use. A converter for which T is compatible with typeToConvert. + + + Represents a result that when executed will produce an Unauthorized (401) response. + + This result creates an with status code: 401. + + + + OData error. + + + + + Initializes a new instance of the class. + + Error message. + + + + Initializes a new instance of the class. + + An object. + + + + + + + Represents a result that when executed will produce an UnprocessableEntity (422) response. + + This result creates an with status code: 422. + + + + OData error. + + + + + Initializes a new instance of the class. + + Error message. + + + + Initializes a new instance of the class. + + An object. + + + + Represents an action result that is a response to a PUT, PATCH, or a MERGE operation on an OData entity. @@ -12121,6 +12288,91 @@ An with the specified values. This function uses types that are AspNetCore-specific. + + + Creates a that when executed will produce a Bad Request (400) response. + + Error message. + A with the specified values. + + + + Creates a that when executed will produce a Bad Request (400) response. + + An object. + A with the specified values. + + + + Creates a that when executed will produce a Not Found (404) response. + + Error message. + A with the specified values. + + + + Creates a that when executed will produce a Not Found (404) response. + + An object. + A with the specified values. + + + + Creates a that when executed will produce a Unauthorized (401) response. + + Error message. + An with the specified values. + + + + Creates a that when executed will produce a Unauthorized (401) response. + + An object. + An with the specified values. + + + + Creates a that when executed will produce a Conflict (409) response. + + Error message. + A with the specified values. + + + + Creates a that when executed will produce a Conflict (409) response. + + An object. + A with the specified values. + + + + Creates a that when executed will produce an UnprocessableEntity (422) response. + + Error message. + An with the specified values. + + + + Creates a that when executed will produce an UnprocessableEntity (422) response. + + An object. + An with the specified values. + + + + Creates an that when executed will produce an response. + + Http error code. + Error message. + An with the specified values. + + + + Creates an that when executed will produce an response. + + An object. + An with the specified values. + The convention for . diff --git a/src/Microsoft.AspNetCore.OData/PublicAPI.Unshipped.txt b/src/Microsoft.AspNetCore.OData/PublicAPI.Unshipped.txt index e40289656..13bb98de2 100644 --- a/src/Microsoft.AspNetCore.OData/PublicAPI.Unshipped.txt +++ b/src/Microsoft.AspNetCore.OData/PublicAPI.Unshipped.txt @@ -1132,8 +1132,26 @@ Microsoft.AspNetCore.OData.Query.Wrapper.DynamicTypeWrapper.TryGetPropertyValue( Microsoft.AspNetCore.OData.Query.Wrapper.ISelectExpandWrapper Microsoft.AspNetCore.OData.Query.Wrapper.ISelectExpandWrapper.ToDictionary() -> System.Collections.Generic.IDictionary Microsoft.AspNetCore.OData.Query.Wrapper.ISelectExpandWrapper.ToDictionary(System.Func propertyMapperProvider) -> System.Collections.Generic.IDictionary +Microsoft.AspNetCore.OData.Results.BadRequestODataResult +Microsoft.AspNetCore.OData.Results.BadRequestODataResult.BadRequestODataResult(Microsoft.OData.ODataError odataError) -> void +Microsoft.AspNetCore.OData.Results.BadRequestODataResult.BadRequestODataResult(string message) -> void +Microsoft.AspNetCore.OData.Results.BadRequestODataResult.Error.get -> Microsoft.OData.ODataError +Microsoft.AspNetCore.OData.Results.ConflictODataResult +Microsoft.AspNetCore.OData.Results.ConflictODataResult.ConflictODataResult(Microsoft.OData.ODataError odataError) -> void +Microsoft.AspNetCore.OData.Results.ConflictODataResult.ConflictODataResult(string message) -> void +Microsoft.AspNetCore.OData.Results.ConflictODataResult.Error.get -> Microsoft.OData.ODataError Microsoft.AspNetCore.OData.Results.CreatedODataResult Microsoft.AspNetCore.OData.Results.CreatedODataResult.CreatedODataResult(T entity) -> void +Microsoft.AspNetCore.OData.Results.IODataErrorResult +Microsoft.AspNetCore.OData.Results.IODataErrorResult.Error.get -> Microsoft.OData.ODataError +Microsoft.AspNetCore.OData.Results.NotFoundODataResult +Microsoft.AspNetCore.OData.Results.NotFoundODataResult.Error.get -> Microsoft.OData.ODataError +Microsoft.AspNetCore.OData.Results.NotFoundODataResult.NotFoundODataResult(Microsoft.OData.ODataError odataError) -> void +Microsoft.AspNetCore.OData.Results.NotFoundODataResult.NotFoundODataResult(string message) -> void +Microsoft.AspNetCore.OData.Results.ODataErrorResult +Microsoft.AspNetCore.OData.Results.ODataErrorResult.Error.get -> Microsoft.OData.ODataError +Microsoft.AspNetCore.OData.Results.ODataErrorResult.ODataErrorResult(Microsoft.OData.ODataError odataError) -> void +Microsoft.AspNetCore.OData.Results.ODataErrorResult.ODataErrorResult(string errorCode, string message) -> void Microsoft.AspNetCore.OData.Results.PageResult Microsoft.AspNetCore.OData.Results.PageResult.Count.get -> long? Microsoft.AspNetCore.OData.Results.PageResult.NextPageLink.get -> System.Uri @@ -1148,6 +1166,14 @@ Microsoft.AspNetCore.OData.Results.SingleResult.SingleResult(System.Linq.IQuerya Microsoft.AspNetCore.OData.Results.SingleResult Microsoft.AspNetCore.OData.Results.SingleResult.Queryable.get -> System.Linq.IQueryable Microsoft.AspNetCore.OData.Results.SingleResult.SingleResult(System.Linq.IQueryable queryable) -> void +Microsoft.AspNetCore.OData.Results.UnauthorizedODataResult +Microsoft.AspNetCore.OData.Results.UnauthorizedODataResult.Error.get -> Microsoft.OData.ODataError +Microsoft.AspNetCore.OData.Results.UnauthorizedODataResult.UnauthorizedODataResult(Microsoft.OData.ODataError odataError) -> void +Microsoft.AspNetCore.OData.Results.UnauthorizedODataResult.UnauthorizedODataResult(string message) -> void +Microsoft.AspNetCore.OData.Results.UnprocessableEntityODataResult +Microsoft.AspNetCore.OData.Results.UnprocessableEntityODataResult.Error.get -> Microsoft.OData.ODataError +Microsoft.AspNetCore.OData.Results.UnprocessableEntityODataResult.UnprocessableEntityODataResult(Microsoft.OData.ODataError odataError) -> void +Microsoft.AspNetCore.OData.Results.UnprocessableEntityODataResult.UnprocessableEntityODataResult(string message) -> void Microsoft.AspNetCore.OData.Results.UpdatedODataResult Microsoft.AspNetCore.OData.Results.UpdatedODataResult.UpdatedODataResult(T entity) -> void Microsoft.AspNetCore.OData.Routing.Attributes.ODataAttributeRoutingAttribute @@ -1436,8 +1462,14 @@ override Microsoft.AspNetCore.OData.Query.ETag.TrySetMember(System.Dynamic.SetMe override Microsoft.AspNetCore.OData.Query.ETag.ApplyTo(System.Linq.IQueryable query) -> System.Linq.IQueryable override Microsoft.AspNetCore.OData.Query.ODataQueryOptions.ApplyTo(System.Linq.IQueryable query) -> System.Linq.IQueryable override Microsoft.AspNetCore.OData.Query.ODataQueryOptions.ApplyTo(System.Linq.IQueryable query, Microsoft.AspNetCore.OData.Query.ODataQuerySettings querySettings) -> System.Linq.IQueryable +override Microsoft.AspNetCore.OData.Results.BadRequestODataResult.ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) -> System.Threading.Tasks.Task +override Microsoft.AspNetCore.OData.Results.ConflictODataResult.ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) -> System.Threading.Tasks.Task override Microsoft.AspNetCore.OData.Results.CreatedODataResult.ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) -> System.Threading.Tasks.Task +override Microsoft.AspNetCore.OData.Results.NotFoundODataResult.ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) -> System.Threading.Tasks.Task +override Microsoft.AspNetCore.OData.Results.ODataErrorResult.ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) -> System.Threading.Tasks.Task override Microsoft.AspNetCore.OData.Results.PageResult.ToDictionary() -> System.Collections.Generic.IDictionary +override Microsoft.AspNetCore.OData.Results.UnauthorizedODataResult.ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) -> System.Threading.Tasks.Task +override Microsoft.AspNetCore.OData.Results.UnprocessableEntityODataResult.ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) -> System.Threading.Tasks.Task override Microsoft.AspNetCore.OData.Results.UpdatedODataResult.ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) -> System.Threading.Tasks.Task override Microsoft.AspNetCore.OData.Routing.Conventions.ActionRoutingConvention.AppliesToAction(Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) -> bool override Microsoft.AspNetCore.OData.Routing.Conventions.ActionRoutingConvention.IsOperationParameterMatched(Microsoft.OData.Edm.IEdmOperation operation, Microsoft.AspNetCore.Mvc.ApplicationModels.ActionModel action) -> bool @@ -1822,7 +1854,19 @@ virtual Microsoft.AspNetCore.OData.Query.Validator.SkipTokenQueryValidator.Valid virtual Microsoft.AspNetCore.OData.Query.Validator.TopQueryValidator.Validate(Microsoft.AspNetCore.OData.Query.TopQueryOption topQueryOption, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings validationSettings) -> void virtual Microsoft.AspNetCore.OData.Results.CreatedODataResult.Entity.get -> T virtual Microsoft.AspNetCore.OData.Results.UpdatedODataResult.Entity.get -> T +virtual Microsoft.AspNetCore.OData.Routing.Controllers.ODataController.BadRequest(Microsoft.OData.ODataError odataError) -> Microsoft.AspNetCore.OData.Results.BadRequestODataResult +virtual Microsoft.AspNetCore.OData.Routing.Controllers.ODataController.BadRequest(string message) -> Microsoft.AspNetCore.OData.Results.BadRequestODataResult +virtual Microsoft.AspNetCore.OData.Routing.Controllers.ODataController.Conflict(Microsoft.OData.ODataError odataError) -> Microsoft.AspNetCore.OData.Results.ConflictODataResult +virtual Microsoft.AspNetCore.OData.Routing.Controllers.ODataController.Conflict(string message) -> Microsoft.AspNetCore.OData.Results.ConflictODataResult virtual Microsoft.AspNetCore.OData.Routing.Controllers.ODataController.Created(TEntity entity) -> Microsoft.AspNetCore.OData.Results.CreatedODataResult +virtual Microsoft.AspNetCore.OData.Routing.Controllers.ODataController.NotFound(Microsoft.OData.ODataError odataError) -> Microsoft.AspNetCore.OData.Results.NotFoundODataResult +virtual Microsoft.AspNetCore.OData.Routing.Controllers.ODataController.NotFound(string message) -> Microsoft.AspNetCore.OData.Results.NotFoundODataResult +virtual Microsoft.AspNetCore.OData.Routing.Controllers.ODataController.ODataErrorResult(Microsoft.OData.ODataError odataError) -> Microsoft.AspNetCore.OData.Results.ODataErrorResult +virtual Microsoft.AspNetCore.OData.Routing.Controllers.ODataController.ODataErrorResult(string errorCode, string message) -> Microsoft.AspNetCore.OData.Results.ODataErrorResult +virtual Microsoft.AspNetCore.OData.Routing.Controllers.ODataController.Unauthorized(Microsoft.OData.ODataError odataError) -> Microsoft.AspNetCore.OData.Results.UnauthorizedODataResult +virtual Microsoft.AspNetCore.OData.Routing.Controllers.ODataController.Unauthorized(string message) -> Microsoft.AspNetCore.OData.Results.UnauthorizedODataResult +virtual Microsoft.AspNetCore.OData.Routing.Controllers.ODataController.UnprocessableEntity(Microsoft.OData.ODataError odataError) -> Microsoft.AspNetCore.OData.Results.UnprocessableEntityODataResult +virtual Microsoft.AspNetCore.OData.Routing.Controllers.ODataController.UnprocessableEntity(string message) -> Microsoft.AspNetCore.OData.Results.UnprocessableEntityODataResult virtual Microsoft.AspNetCore.OData.Routing.Controllers.ODataController.Updated(TEntity entity) -> Microsoft.AspNetCore.OData.Results.UpdatedODataResult virtual Microsoft.AspNetCore.OData.Routing.Conventions.AttributeRoutingConvention.AppliesToAction(Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) -> bool virtual Microsoft.AspNetCore.OData.Routing.Conventions.AttributeRoutingConvention.AppliesToController(Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) -> bool diff --git a/src/Microsoft.AspNetCore.OData/Results/BadRequestODataResult.cs b/src/Microsoft.AspNetCore.OData/Results/BadRequestODataResult.cs new file mode 100644 index 000000000..ccd3c6b39 --- /dev/null +++ b/src/Microsoft.AspNetCore.OData/Results/BadRequestODataResult.cs @@ -0,0 +1,74 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) .NET Foundation and Contributors. All rights reserved. +// See License.txt in the project root for license information. +// +//------------------------------------------------------------------------------ + +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.OData; +using ErrorUtils = Microsoft.AspNetCore.OData.Error; + +namespace Microsoft.AspNetCore.OData.Results +{ + /// + /// Represents a result that when executed will produce a Bad Request (400) response. + /// + /// This result creates an with status code: 400. + public class BadRequestODataResult : BadRequestResult, IODataErrorResult + { + private const string errorCode = "400"; + + /// + /// OData error. + /// + public ODataError Error { get; } + + /// + /// Initializes a new instance of the class. + /// + /// Error message. + public BadRequestODataResult(string message) + { + if (string.IsNullOrEmpty(message)) + { + throw ErrorUtils.ArgumentNullOrEmpty(nameof(message)); + } + + Error = new ODataError + { + Message = message, + ErrorCode = errorCode + }; + } + + /// + /// Initializes a new instance of the class. + /// + /// An object. + public BadRequestODataResult(ODataError odataError) + { + if (odataError == null) + { + throw ErrorUtils.ArgumentNull(nameof(odataError)); + } + + ErrorUtils.ValidateErrorCode(errorCode, odataError); + + Error = odataError; + } + + /// + public async override Task ExecuteResultAsync(ActionContext context) + { + ObjectResult objectResult = new ObjectResult(Error) + { + StatusCode = StatusCodes.Status400BadRequest + }; + + await objectResult.ExecuteResultAsync(context).ConfigureAwait(false); + } + } +} diff --git a/src/Microsoft.AspNetCore.OData/Results/ConflictODataResult.cs b/src/Microsoft.AspNetCore.OData/Results/ConflictODataResult.cs new file mode 100644 index 000000000..f016f34d0 --- /dev/null +++ b/src/Microsoft.AspNetCore.OData/Results/ConflictODataResult.cs @@ -0,0 +1,74 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) .NET Foundation and Contributors. All rights reserved. +// See License.txt in the project root for license information. +// +//------------------------------------------------------------------------------ + +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.OData; +using ErrorUtils = Microsoft.AspNetCore.OData.Error; + +namespace Microsoft.AspNetCore.OData.Results +{ + /// + /// Represents a result that when executed will produce a Conflict (409) response. + /// + /// This result creates an with status code: 409. + public class ConflictODataResult : ConflictResult, IODataErrorResult + { + private const string errorCode = "409"; + + /// + /// OData error. + /// + public ODataError Error { get; } + + /// + /// Initializes a new instance of the class. + /// + /// Error message. + public ConflictODataResult(string message) + { + if (string.IsNullOrEmpty(message)) + { + throw ErrorUtils.ArgumentNullOrEmpty(nameof(message)); + } + + Error = new ODataError + { + Message = message, + ErrorCode = errorCode + }; + } + + /// + /// Initializes a new instance of the class. + /// + /// An object. + public ConflictODataResult(ODataError odataError) + { + if (odataError == null) + { + throw ErrorUtils.ArgumentNull(nameof(odataError)); + } + + ErrorUtils.ValidateErrorCode(errorCode, odataError); + + Error = odataError; + } + + /// + public async override Task ExecuteResultAsync(ActionContext context) + { + ObjectResult objectResult = new ObjectResult(Error) + { + StatusCode = StatusCodes.Status409Conflict + }; + + await objectResult.ExecuteResultAsync(context).ConfigureAwait(false); + } + } +} diff --git a/src/Microsoft.AspNetCore.OData/Results/IODataErrorResult.cs b/src/Microsoft.AspNetCore.OData/Results/IODataErrorResult.cs new file mode 100644 index 000000000..307a59e41 --- /dev/null +++ b/src/Microsoft.AspNetCore.OData/Results/IODataErrorResult.cs @@ -0,0 +1,24 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) .NET Foundation and Contributors. All rights reserved. +// See License.txt in the project root for license information. +// +//------------------------------------------------------------------------------ + +using Microsoft.OData; + +namespace Microsoft.AspNetCore.OData.Results +{ + /// + /// Provide the interface for the details of a given OData error result. + /// + public interface IODataErrorResult + { + /// + /// OData error. + /// +#pragma warning disable CA1716 // Identifiers should not match keywords + ODataError Error { get; } +#pragma warning restore CA1716 // Identifiers should not match keywords + } +} diff --git a/src/Microsoft.AspNetCore.OData/Results/NotFoundODataResult.cs b/src/Microsoft.AspNetCore.OData/Results/NotFoundODataResult.cs new file mode 100644 index 000000000..b64c6dd42 --- /dev/null +++ b/src/Microsoft.AspNetCore.OData/Results/NotFoundODataResult.cs @@ -0,0 +1,74 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) .NET Foundation and Contributors. All rights reserved. +// See License.txt in the project root for license information. +// +//------------------------------------------------------------------------------ + +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.OData; +using ErrorUtils = Microsoft.AspNetCore.OData.Error; + +namespace Microsoft.AspNetCore.OData.Results +{ + /// + /// Represents a result that when executed will produce a Not Found (404) response. + /// + /// This result creates an with status code: 404. + public class NotFoundODataResult : NotFoundResult, IODataErrorResult + { + private const string errorCode = "404"; + + /// + /// OData error. + /// + public ODataError Error { get; } + + /// + /// Initializes a new instance of the class. + /// + /// Error message. + public NotFoundODataResult(string message) + { + if (string.IsNullOrEmpty(message)) + { + throw ErrorUtils.ArgumentNullOrEmpty(nameof(message)); + } + + Error = new ODataError + { + Message = message, + ErrorCode = errorCode + }; + } + + /// + /// Initializes a new instance of the class. + /// + /// An object. + public NotFoundODataResult(ODataError odataError) + { + if (odataError == null) + { + throw ErrorUtils.ArgumentNull(nameof(odataError)); + } + + ErrorUtils.ValidateErrorCode(errorCode, odataError); + + Error = odataError; + } + + /// + public async override Task ExecuteResultAsync(ActionContext context) + { + ObjectResult objectResult = new ObjectResult(Error) + { + StatusCode = StatusCodes.Status404NotFound + }; + + await objectResult.ExecuteResultAsync(context).ConfigureAwait(false); + } + } +} diff --git a/src/Microsoft.AspNetCore.OData/Results/ODataErrorResult.cs b/src/Microsoft.AspNetCore.OData/Results/ODataErrorResult.cs new file mode 100644 index 000000000..22deec5c2 --- /dev/null +++ b/src/Microsoft.AspNetCore.OData/Results/ODataErrorResult.cs @@ -0,0 +1,77 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) .NET Foundation and Contributors. All rights reserved. +// See License.txt in the project root for license information. +// +//------------------------------------------------------------------------------ + +using System; +using System.Globalization; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.OData; +using ErrorUtils = Microsoft.AspNetCore.OData.Error; + +namespace Microsoft.AspNetCore.OData.Results +{ + /// + /// Represents a result that when executed will produce an . + /// + /// This result creates an response. + public class ODataErrorResult : ActionResult, IODataErrorResult + { + /// + /// OData error. + /// + public ODataError Error { get; } + + /// + /// Initializes a new instance of the class. + /// + /// Error code. + /// Error message. + public ODataErrorResult(string errorCode, string message) + { + if (string.IsNullOrEmpty(errorCode)) + { + throw ErrorUtils.ArgumentNullOrEmpty(nameof(errorCode)); + } + + if (string.IsNullOrEmpty(message)) + { + throw ErrorUtils.ArgumentNullOrEmpty(nameof(message)); + } + + Error = new ODataError + { + ErrorCode = errorCode, + Message = message + }; + } + + /// + /// Initializes a new instance of the class. + /// + /// An object. + public ODataErrorResult(ODataError odataError) + { + if (odataError == null) + { + throw ErrorUtils.ArgumentNull(nameof(odataError)); + } + + Error = odataError; + } + + /// + public async override Task ExecuteResultAsync(ActionContext context) + { + ObjectResult objectResult = new ObjectResult(Error) + { + StatusCode = Convert.ToInt32(Error.ErrorCode, CultureInfo.InvariantCulture) + }; + + await objectResult.ExecuteResultAsync(context).ConfigureAwait(false); + } + } +} diff --git a/src/Microsoft.AspNetCore.OData/Results/UnauthorizedODataResult.cs b/src/Microsoft.AspNetCore.OData/Results/UnauthorizedODataResult.cs new file mode 100644 index 000000000..26d98309f --- /dev/null +++ b/src/Microsoft.AspNetCore.OData/Results/UnauthorizedODataResult.cs @@ -0,0 +1,74 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) .NET Foundation and Contributors. All rights reserved. +// See License.txt in the project root for license information. +// +//------------------------------------------------------------------------------ + +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.OData; +using ErrorUtils = Microsoft.AspNetCore.OData.Error; + +namespace Microsoft.AspNetCore.OData.Results +{ + /// + /// Represents a result that when executed will produce an Unauthorized (401) response. + /// + /// This result creates an with status code: 401. + public class UnauthorizedODataResult : UnauthorizedResult, IODataErrorResult + { + private const string errorCode = "401"; + + /// + /// OData error. + /// + public ODataError Error { get; } + + /// + /// Initializes a new instance of the class. + /// + /// Error message. + public UnauthorizedODataResult(string message) + { + if (string.IsNullOrEmpty(message)) + { + throw ErrorUtils.ArgumentNullOrEmpty(nameof(message)); + } + + Error = new ODataError + { + Message = message, + ErrorCode = errorCode + }; + } + + /// + /// Initializes a new instance of the class. + /// + /// An object. + public UnauthorizedODataResult(ODataError odataError) + { + if (odataError == null) + { + throw ErrorUtils.ArgumentNull(nameof(odataError)); + } + + ErrorUtils.ValidateErrorCode(errorCode, odataError); + + Error = odataError; + } + + /// + public async override Task ExecuteResultAsync(ActionContext context) + { + ObjectResult objectResult = new ObjectResult(Error) + { + StatusCode = StatusCodes.Status401Unauthorized + }; + + await objectResult.ExecuteResultAsync(context).ConfigureAwait(false); + } + } +} diff --git a/src/Microsoft.AspNetCore.OData/Results/UnprocessableEntityODataResult .cs b/src/Microsoft.AspNetCore.OData/Results/UnprocessableEntityODataResult .cs new file mode 100644 index 000000000..24e0e86dd --- /dev/null +++ b/src/Microsoft.AspNetCore.OData/Results/UnprocessableEntityODataResult .cs @@ -0,0 +1,74 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) .NET Foundation and Contributors. All rights reserved. +// See License.txt in the project root for license information. +// +//------------------------------------------------------------------------------ + +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.OData; +using ErrorUtils = Microsoft.AspNetCore.OData.Error; + +namespace Microsoft.AspNetCore.OData.Results +{ + /// + /// Represents a result that when executed will produce an UnprocessableEntity (422) response. + /// + /// This result creates an with status code: 422. + public class UnprocessableEntityODataResult : UnprocessableEntityResult, IODataErrorResult + { + private const string errorCode = "422"; + + /// + /// OData error. + /// + public ODataError Error { get; } + + /// + /// Initializes a new instance of the class. + /// + /// Error message. + public UnprocessableEntityODataResult(string message) + { + if (string.IsNullOrEmpty(message)) + { + throw ErrorUtils.ArgumentNullOrEmpty(nameof(message)); + } + + Error = new ODataError + { + Message = message, + ErrorCode = errorCode + }; + } + + /// + /// Initializes a new instance of the class. + /// + /// An object. + public UnprocessableEntityODataResult(ODataError odataError) + { + if (odataError == null) + { + throw ErrorUtils.ArgumentNull(nameof(odataError)); + } + + ErrorUtils.ValidateErrorCode(errorCode, odataError); + + Error = odataError; + } + + /// + public async override Task ExecuteResultAsync(ActionContext context) + { + ObjectResult objectResult = new ObjectResult(Error) + { + StatusCode = StatusCodes.Status422UnprocessableEntity + }; + + await objectResult.ExecuteResultAsync(context).ConfigureAwait(false); + } + } +} diff --git a/src/Microsoft.AspNetCore.OData/Routing/Controllers/ODataController.cs b/src/Microsoft.AspNetCore.OData/Routing/Controllers/ODataController.cs index 1be2ecf19..ab100bc65 100644 --- a/src/Microsoft.AspNetCore.OData/Routing/Controllers/ODataController.cs +++ b/src/Microsoft.AspNetCore.OData/Routing/Controllers/ODataController.cs @@ -8,6 +8,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.OData.Results; using Microsoft.AspNetCore.OData.Routing.Attributes; +using Microsoft.OData; namespace Microsoft.AspNetCore.OData.Routing.Controllers { @@ -52,5 +53,126 @@ protected virtual UpdatedODataResult Updated(TEntity entity) return new UpdatedODataResult(entity); } + + /// + /// Creates a that when executed will produce a Bad Request (400) response. + /// + /// Error message. + /// A with the specified values. + protected virtual BadRequestODataResult BadRequest(string message) + { + return new BadRequestODataResult(message); + } + + /// + /// Creates a that when executed will produce a Bad Request (400) response. + /// + /// An object. + /// A with the specified values. + protected virtual BadRequestODataResult BadRequest(ODataError odataError) + { + return new BadRequestODataResult(odataError); + } + + /// + /// Creates a that when executed will produce a Not Found (404) response. + /// + /// Error message. + /// A with the specified values. + protected virtual NotFoundODataResult NotFound(string message) + { + return new NotFoundODataResult(message); + } + + /// + /// Creates a that when executed will produce a Not Found (404) response. + /// + /// An object. + /// A with the specified values. + protected virtual NotFoundODataResult NotFound(ODataError odataError) + { + return new NotFoundODataResult(odataError); + } + + /// + /// Creates a that when executed will produce a Unauthorized (401) response. + /// + /// Error message. + /// An with the specified values. + protected virtual UnauthorizedODataResult Unauthorized(string message) + { + return new UnauthorizedODataResult(message); + } + + /// + /// Creates a that when executed will produce a Unauthorized (401) response. + /// + /// An object. + /// An with the specified values. + protected virtual UnauthorizedODataResult Unauthorized(ODataError odataError) + { + return new UnauthorizedODataResult(odataError); + } + + /// + /// Creates a that when executed will produce a Conflict (409) response. + /// + /// Error message. + /// A with the specified values. + protected virtual ConflictODataResult Conflict(string message) + { + return new ConflictODataResult(message); + } + + /// + /// Creates a that when executed will produce a Conflict (409) response. + /// + /// An object. + /// A with the specified values. + protected virtual ConflictODataResult Conflict(ODataError odataError) + { + return new ConflictODataResult(odataError); + } + + /// + /// Creates a that when executed will produce an UnprocessableEntity (422) response. + /// + /// Error message. + /// An with the specified values. + protected virtual UnprocessableEntityODataResult UnprocessableEntity(string message) + { + return new UnprocessableEntityODataResult(message); + } + + /// + /// Creates a that when executed will produce an UnprocessableEntity (422) response. + /// + /// An object. + /// An with the specified values. + protected virtual UnprocessableEntityODataResult UnprocessableEntity(ODataError odataError) + { + return new UnprocessableEntityODataResult(odataError); + } + + /// + /// Creates an that when executed will produce an response. + /// + /// Http error code. + /// Error message. + /// An with the specified values. + protected virtual ODataErrorResult ODataErrorResult(string errorCode, string message) + { + return new ODataErrorResult(errorCode, message); + } + + /// + /// Creates an that when executed will produce an response. + /// + /// An object. + /// An with the specified values. + protected virtual ODataErrorResult ODataErrorResult(ODataError odataError) + { + return new ODataErrorResult(odataError); + } } } diff --git a/test/Microsoft.AspNetCore.OData.E2E.Tests/ODataErrors/ODataErrorsController.cs b/test/Microsoft.AspNetCore.OData.E2E.Tests/ODataErrors/ODataErrorsController.cs new file mode 100644 index 000000000..33c732025 --- /dev/null +++ b/test/Microsoft.AspNetCore.OData.E2E.Tests/ODataErrors/ODataErrorsController.cs @@ -0,0 +1,115 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) .NET Foundation and Contributors. All rights reserved. +// See License.txt in the project root for license information. +// +//------------------------------------------------------------------------------ + +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.OData.Formatter; +using Microsoft.AspNetCore.OData.Query; +using Microsoft.AspNetCore.OData.Routing.Controllers; +using Microsoft.OData; + +namespace Microsoft.AspNetCore.OData.E2E.Tests.ODataErrors +{ + public class CustomersController : ODataController + { + [EnableQuery] + public IActionResult Get() + { + return Unauthorized("Not authorized to access this resource."); + } + + [EnableQuery] + public IActionResult Get(int key) + { + return NotFound($"Customer with key: {key} not found."); + } + + public IActionResult Post([FromBody] Customer customer) + { + return UnprocessableEntity("Unprocessable customer object."); + } + + public IActionResult Patch([FromODataUri] int key,[FromBody] Customer customer) + { + return Conflict("Conflict during update."); + } + + public IActionResult Put([FromODataUri] int key, [FromBody] Customer customer) + { + return ODataErrorResult("400", "Bad request during PUT."); + } + + public IActionResult Delete(int key) + { + return BadRequest("Bad request on delete."); + } + } + + public class OrdersController : ODataController + { + [EnableQuery] + public IActionResult Get() + { + ODataError odataError = new ODataError() + { + ErrorCode = "401", + Message = "Not authorized to access this resource." + }; + return Unauthorized(odataError); + } + + [EnableQuery] + public IActionResult Get(int key) + { + ODataError odataError = new ODataError() + { + ErrorCode = "404", + Message = $"Order with key: {key} not found." + }; + return NotFound(odataError); + } + + public IActionResult Post([FromBody] Order order) + { + ODataError odataError = new ODataError() + { + ErrorCode = "422", + Message = "Unprocessable order object." + }; + return UnprocessableEntity(odataError); + } + + public IActionResult Patch([FromODataUri] int key, [FromBody] Order order) + { + ODataError odataError = new ODataError() + { + ErrorCode = "409", + Message = "Conflict during update." + }; + return Conflict(odataError); + } + + public IActionResult Put([FromODataUri] int key, [FromBody] Order order) + { + ODataError odataError = new ODataError() + { + ErrorCode = "400", + Message = "Bad request during PUT." + }; + return ODataErrorResult(odataError); + } + + public IActionResult Delete(int key) + { + ODataError odataError = new ODataError() + { + ErrorCode = "400", + Message = "Bad request on delete." + }; + return BadRequest(odataError); + } + } +} diff --git a/test/Microsoft.AspNetCore.OData.E2E.Tests/ODataErrors/ODataErrorsDataModel.cs b/test/Microsoft.AspNetCore.OData.E2E.Tests/ODataErrors/ODataErrorsDataModel.cs new file mode 100644 index 000000000..505db26f1 --- /dev/null +++ b/test/Microsoft.AspNetCore.OData.E2E.Tests/ODataErrors/ODataErrorsDataModel.cs @@ -0,0 +1,27 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) .NET Foundation and Contributors. All rights reserved. +// See License.txt in the project root for license information. +// +//------------------------------------------------------------------------------ + +using System.Collections.Generic; + +namespace Microsoft.AspNetCore.OData.E2E.Tests.ODataErrors +{ + public class Customer + { + public int Id { get; set; } + + public string Name { get; set; } + + public List Orders { get; set; } + } + + public class Order + { + public int Id { get; set; } + + public string Name { get; set; } + } +} diff --git a/test/Microsoft.AspNetCore.OData.E2E.Tests/ODataErrors/ODataErrorsEdmModel.cs b/test/Microsoft.AspNetCore.OData.E2E.Tests/ODataErrors/ODataErrorsEdmModel.cs new file mode 100644 index 000000000..1eeceafdd --- /dev/null +++ b/test/Microsoft.AspNetCore.OData.E2E.Tests/ODataErrors/ODataErrorsEdmModel.cs @@ -0,0 +1,24 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) .NET Foundation and Contributors. All rights reserved. +// See License.txt in the project root for license information. +// +//------------------------------------------------------------------------------ + +using Microsoft.OData.Edm; +using Microsoft.OData.ModelBuilder; + +namespace Microsoft.AspNetCore.OData.E2E.Tests.ODataErrors +{ + public class ODataErrorsEdmModel + { + public static IEdmModel GetEdmModel() + { + var builder = new ODataConventionModelBuilder(); + builder.EntitySet("Customers"); + builder.EntitySet("Orders"); + IEdmModel model = builder.GetEdmModel(); + return model; + } + } +} diff --git a/test/Microsoft.AspNetCore.OData.E2E.Tests/ODataErrors/ODataErrorsTests.cs b/test/Microsoft.AspNetCore.OData.E2E.Tests/ODataErrors/ODataErrorsTests.cs new file mode 100644 index 000000000..df278e8bf --- /dev/null +++ b/test/Microsoft.AspNetCore.OData.E2E.Tests/ODataErrors/ODataErrorsTests.cs @@ -0,0 +1,198 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) .NET Foundation and Contributors. All rights reserved. +// See License.txt in the project root for license information. +// +//------------------------------------------------------------------------------ + +using Microsoft.AspNetCore.OData.TestCommon; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.OData.Edm; +using System.Net; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading.Tasks; +using Xunit; +using Xunit.Abstractions; + +namespace Microsoft.AspNetCore.OData.E2E.Tests.ODataErrors +{ + public class ODataErrorsTests : WebApiTestBase + { + private readonly ITestOutputHelper output; + + public ODataErrorsTests(WebApiTestFixture fixture, ITestOutputHelper output) + : base(fixture) + { + this.output = output; + } + + protected static void UpdateConfigureServices(IServiceCollection services) + { + IEdmModel edmModel = ODataErrorsEdmModel.GetEdmModel(); + + services.ConfigureControllers(typeof(CustomersController), + typeof(OrdersController)); + + services.AddControllers().AddOData(opt => + opt.Count().Filter().OrderBy().Expand().SetMaxTop(null).Select().AddRouteComponents("odataerrors", edmModel)); + } + + [Theory] + [InlineData("odataerrors/Customers(1)", "{\"error\":{\"code\":\"404\",\"message\":\"Customer with key: 1 not found.\"}}")] + [InlineData("odataerrors/Orders(1)", "{\"error\":{\"code\":\"404\",\"message\":\"Order with key: 1 not found.\"}}")] + public async Task NotFoundResponseFromODataControllerIsSerializedAsODataError(string queryUrl, string expectedResponse) + { + // Arrange + using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, queryUrl); + request.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json;odata.metadata=none")); + using HttpClient client = CreateClient(); + + // Act + using HttpResponseMessage response = await client.SendAsync(request); + + // Assert + Assert.NotNull(response); + Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); + Assert.NotNull(response.Content); + + string payload = await response.Content.ReadAsStringAsync(); + Assert.Equal(expectedResponse, payload); + } + + [Theory] + [InlineData("odataerrors/Customers")] + [InlineData("odataerrors/Orders")] + public async Task UnauthorizedResponseFromODataControllerIsSerializedAsODataError(string queryUrl) + { + // Arrange + const string expectedResponse = "{\"error\":{\"code\":\"401\",\"message\":\"Not authorized to access this resource.\"}}"; + + using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, queryUrl); + request.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json;odata.metadata=none")); + using HttpClient client = CreateClient(); + + // Act + using HttpResponseMessage response = await client.SendAsync(request); + + // Assert + Assert.NotNull(response); + Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); + Assert.NotNull(response.Content); + + string payload = await response.Content.ReadAsStringAsync(); + Assert.Equal(expectedResponse, payload); + } + + [Theory] + [InlineData("odataerrors/Customers(1000)", @"{{'@odata.type':'#Microsoft.AspNetCore.OData.E2E.Tests.ODataErrors.Customer', + 'ID':1000,'Name':'Customer 1000,}}")] + [InlineData("odataerrors/Orders(1000)", @"{{'@odata.type':'#Microsoft.AspNetCore.OData.E2E.Tests.ODataErrors.Order', + 'ID':1000,'Name':'Order 1000,}}")] + public async Task ConflictResponseFromODataControllerIsSerializedAsODataError(string queryUrl, string requestContent) + { + // Arrange + const string expectedResponse = "{\"error\":{\"code\":\"409\",\"message\":\"Conflict during update.\"}}"; + + using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Patch, queryUrl); + using var content = new StringContent(requestContent); + request.Content = content; + request.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json;odata.metadata=none")); + using HttpClient client = CreateClient(); + + // Act + using HttpResponseMessage response = await client.SendAsync(request); + + // Assert + Assert.NotNull(response); + Assert.Equal(HttpStatusCode.Conflict, response.StatusCode); + Assert.NotNull(response.Content); + + string payload = await response.Content.ReadAsStringAsync(); + Assert.Equal(expectedResponse, payload); + } + + [Theory] + [InlineData("odataerrors/Customers(1)")] + [InlineData("odataerrors/Orders(1)")] + public async Task BadRequestResponseFromODataControllerIsSerializedAsODataError(string queryUrl) + { + // Arrange + const string expectedResponse = "{\"error\":{\"code\":\"400\",\"message\":\"Bad request on delete.\"}}"; + + using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Delete, queryUrl); + request.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json;odata.metadata=none")); + using HttpClient client = CreateClient(); + + // Act + using HttpResponseMessage response = await client.SendAsync(request); + + // Assert + Assert.NotNull(response); + Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); + Assert.NotNull(response.Content); + + string payload = await response.Content.ReadAsStringAsync(); + Assert.Equal(expectedResponse, payload); + } + + [Theory] + [InlineData( + "odataerrors/Customers", + @"{{'@odata.type':'#Microsoft.AspNetCore.OData.E2E.Tests.ODataErrors.Customer', 'ID':1000,'Name':'Customer 1000}}", + "{\"error\":{\"code\":\"422\",\"message\":\"Unprocessable customer object.\"}}")] + [InlineData( + "odataerrors/Orders", + @"{{'@odata.type':'#Microsoft.AspNetCore.OData.E2E.Tests.ODataErrors.Order', 'ID':1000,'Name':'Order 1000}}", + "{\"error\":{\"code\":\"422\",\"message\":\"Unprocessable order object.\"}}")] + public async Task UnprocessableEntityResponseFromODataControllerIsSerializedAsODataError(string queryUrl, string requestContent, string expectedResponse) + { + // Arrange + + using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, queryUrl); + using var content = new StringContent(requestContent); + request.Content = content; + request.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json;odata.metadata=none")); + using HttpClient client = CreateClient(); + + // Act + using HttpResponseMessage response = await client.SendAsync(request); + + // Assert + Assert.NotNull(response); + Assert.Equal(HttpStatusCode.UnprocessableEntity, response.StatusCode); + Assert.NotNull(response.Content); + + string payload = await response.Content.ReadAsStringAsync(); + Assert.Equal(expectedResponse, payload); + } + + [Theory] + [InlineData("odataerrors/Customers(1000)", @"{{'@odata.type':'#Microsoft.AspNetCore.OData.E2E.Tests.ODataErrors.Customer', + 'ID':1000,'Name':'Customer 1000,}}")] + [InlineData("odataerrors/Orders(1000)", @"{{'@odata.type':'#Microsoft.AspNetCore.OData.E2E.Tests.ODataErrors.Order', + 'ID':1000,'Name':'Order 1000,}}")] + public async Task ODataErrorResultResponseFromODataControllerIsSerializedAsODataError(string queryUrl, string requestContent) + { + // Arrange + const string expectedResponse = "{\"error\":{\"code\":\"400\",\"message\":\"Bad request during PUT.\"}}"; + + using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Put, queryUrl); + using var content = new StringContent(requestContent); + request.Content = content; + request.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json;odata.metadata=none")); + using HttpClient client = CreateClient(); + + // Act + using HttpResponseMessage response = await client.SendAsync(request); + + // Assert + Assert.NotNull(response); + Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); + Assert.NotNull(response.Content); + + string payload = await response.Content.ReadAsStringAsync(); + Assert.Equal(expectedResponse, payload); + } + } +} diff --git a/test/Microsoft.AspNetCore.OData.Tests/Microsoft.AspNetCore.OData.Tests.csproj b/test/Microsoft.AspNetCore.OData.Tests/Microsoft.AspNetCore.OData.Tests.csproj index 246f7e6ae..5ee8f8518 100644 --- a/test/Microsoft.AspNetCore.OData.Tests/Microsoft.AspNetCore.OData.Tests.csproj +++ b/test/Microsoft.AspNetCore.OData.Tests/Microsoft.AspNetCore.OData.Tests.csproj @@ -33,11 +33,13 @@ + + diff --git a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net5.bsl b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net5.bsl index 87b1c80ee..33c7d45d6 100644 --- a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net5.bsl +++ b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net5.bsl @@ -1575,6 +1575,10 @@ public sealed class Microsoft.AspNetCore.OData.Query.ODataQueryParameterBindingA public ODataQueryParameterBindingAttribute () } +public interface Microsoft.AspNetCore.OData.Results.IODataErrorResult { + Microsoft.OData.ODataError Error { public abstract get; } +} + [ DataContractAttribute(), ] @@ -1602,6 +1606,30 @@ public abstract class Microsoft.AspNetCore.OData.Results.SingleResult { public static SingleResult`1 Create (IQueryable`1 queryable) } +public class Microsoft.AspNetCore.OData.Results.BadRequestODataResult : Microsoft.AspNetCore.Mvc.BadRequestResult, IActionResult, IClientErrorActionResult, IStatusCodeActionResult, IODataErrorResult { + public BadRequestODataResult (Microsoft.OData.ODataError odataError) + public BadRequestODataResult (string message) + + Microsoft.OData.ODataError Error { public virtual get; } + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task ExecuteResultAsync (Microsoft.AspNetCore.Mvc.ActionContext context) +} + +public class Microsoft.AspNetCore.OData.Results.ConflictODataResult : Microsoft.AspNetCore.Mvc.ConflictResult, IActionResult, IClientErrorActionResult, IStatusCodeActionResult, IODataErrorResult { + public ConflictODataResult (Microsoft.OData.ODataError odataError) + public ConflictODataResult (string message) + + Microsoft.OData.ODataError Error { public virtual get; } + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task ExecuteResultAsync (Microsoft.AspNetCore.Mvc.ActionContext context) +} + public class Microsoft.AspNetCore.OData.Results.CreatedODataResult`1 : Microsoft.AspNetCore.Mvc.ActionResult, IActionResult { public CreatedODataResult`1 (T entity) @@ -1613,6 +1641,30 @@ public class Microsoft.AspNetCore.OData.Results.CreatedODataResult`1 : Microsoft public virtual System.Threading.Tasks.Task ExecuteResultAsync (Microsoft.AspNetCore.Mvc.ActionContext context) } +public class Microsoft.AspNetCore.OData.Results.NotFoundODataResult : Microsoft.AspNetCore.Mvc.NotFoundResult, IActionResult, IClientErrorActionResult, IStatusCodeActionResult, IODataErrorResult { + public NotFoundODataResult (Microsoft.OData.ODataError odataError) + public NotFoundODataResult (string message) + + Microsoft.OData.ODataError Error { public virtual get; } + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task ExecuteResultAsync (Microsoft.AspNetCore.Mvc.ActionContext context) +} + +public class Microsoft.AspNetCore.OData.Results.ODataErrorResult : Microsoft.AspNetCore.Mvc.ActionResult, IActionResult, IODataErrorResult { + public ODataErrorResult (Microsoft.OData.ODataError odataError) + public ODataErrorResult (string errorCode, string message) + + Microsoft.OData.ODataError Error { public virtual get; } + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task ExecuteResultAsync (Microsoft.AspNetCore.Mvc.ActionContext context) +} + [ DataContractAttribute(), ] @@ -1629,6 +1681,30 @@ public class Microsoft.AspNetCore.OData.Results.PageResult`1 : Microsoft.AspNetC public virtual System.Collections.Generic.IDictionary`2[[System.String],[System.Object]] ToDictionary () } +public class Microsoft.AspNetCore.OData.Results.UnauthorizedODataResult : Microsoft.AspNetCore.Mvc.UnauthorizedResult, IActionResult, IClientErrorActionResult, IStatusCodeActionResult, IODataErrorResult { + public UnauthorizedODataResult (Microsoft.OData.ODataError odataError) + public UnauthorizedODataResult (string message) + + Microsoft.OData.ODataError Error { public virtual get; } + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task ExecuteResultAsync (Microsoft.AspNetCore.Mvc.ActionContext context) +} + +public class Microsoft.AspNetCore.OData.Results.UnprocessableEntityODataResult : Microsoft.AspNetCore.Mvc.UnprocessableEntityResult, IActionResult, IClientErrorActionResult, IStatusCodeActionResult, IODataErrorResult { + public UnprocessableEntityODataResult (Microsoft.OData.ODataError odataError) + public UnprocessableEntityODataResult (string message) + + Microsoft.OData.ODataError Error { public virtual get; } + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task ExecuteResultAsync (Microsoft.AspNetCore.Mvc.ActionContext context) +} + public class Microsoft.AspNetCore.OData.Results.UpdatedODataResult`1 : Microsoft.AspNetCore.Mvc.ActionResult, IActionResult { public UpdatedODataResult`1 (T entity) @@ -2882,7 +2958,19 @@ ODataAttributeRoutingAttribute(), public abstract class Microsoft.AspNetCore.OData.Routing.Controllers.ODataController : Microsoft.AspNetCore.Mvc.ControllerBase { protected ODataController () + protected virtual Microsoft.AspNetCore.OData.Results.BadRequestODataResult BadRequest (Microsoft.OData.ODataError odataError) + protected virtual Microsoft.AspNetCore.OData.Results.BadRequestODataResult BadRequest (string message) + protected virtual Microsoft.AspNetCore.OData.Results.ConflictODataResult Conflict (Microsoft.OData.ODataError odataError) + protected virtual Microsoft.AspNetCore.OData.Results.ConflictODataResult Conflict (string message) protected virtual CreatedODataResult`1 Created (TEntity entity) + protected virtual Microsoft.AspNetCore.OData.Results.NotFoundODataResult NotFound (Microsoft.OData.ODataError odataError) + protected virtual Microsoft.AspNetCore.OData.Results.NotFoundODataResult NotFound (string message) + protected virtual Microsoft.AspNetCore.OData.Results.ODataErrorResult ODataErrorResult (Microsoft.OData.ODataError odataError) + protected virtual Microsoft.AspNetCore.OData.Results.ODataErrorResult ODataErrorResult (string errorCode, string message) + protected virtual Microsoft.AspNetCore.OData.Results.UnauthorizedODataResult Unauthorized (Microsoft.OData.ODataError odataError) + protected virtual Microsoft.AspNetCore.OData.Results.UnauthorizedODataResult Unauthorized (string message) + protected virtual Microsoft.AspNetCore.OData.Results.UnprocessableEntityODataResult UnprocessableEntity (Microsoft.OData.ODataError odataError) + protected virtual Microsoft.AspNetCore.OData.Results.UnprocessableEntityODataResult UnprocessableEntity (string message) protected virtual UpdatedODataResult`1 Updated (TEntity entity) } diff --git a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net6.bsl b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net6.bsl new file mode 100644 index 000000000..33c7d45d6 --- /dev/null +++ b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net6.bsl @@ -0,0 +1,3360 @@ +[ +ExtensionAttribute(), +] +public sealed class Microsoft.AspNetCore.OData.ODataApplicationBuilderExtensions { + [ + ExtensionAttribute(), + ] + public static Microsoft.AspNetCore.Builder.IApplicationBuilder UseODataBatching (Microsoft.AspNetCore.Builder.IApplicationBuilder app) + + [ + ExtensionAttribute(), + ] + public static Microsoft.AspNetCore.Builder.IApplicationBuilder UseODataQueryRequest (Microsoft.AspNetCore.Builder.IApplicationBuilder app) + + [ + ExtensionAttribute(), + ] + public static Microsoft.AspNetCore.Builder.IApplicationBuilder UseODataRouteDebug (Microsoft.AspNetCore.Builder.IApplicationBuilder app) + + [ + ExtensionAttribute(), + ] + public static Microsoft.AspNetCore.Builder.IApplicationBuilder UseODataRouteDebug (Microsoft.AspNetCore.Builder.IApplicationBuilder app, string routePattern) +} + +[ +ExtensionAttribute(), +] +public sealed class Microsoft.AspNetCore.OData.ODataMvcBuilderExtensions { + [ + ExtensionAttribute(), + ] + public static Microsoft.Extensions.DependencyInjection.IMvcBuilder AddOData (Microsoft.Extensions.DependencyInjection.IMvcBuilder builder) + + [ + ExtensionAttribute(), + ] + public static Microsoft.Extensions.DependencyInjection.IMvcBuilder AddOData (Microsoft.Extensions.DependencyInjection.IMvcBuilder builder, System.Action`1[[Microsoft.AspNetCore.OData.ODataOptions]] setupAction) + + [ + ExtensionAttribute(), + ] + public static Microsoft.Extensions.DependencyInjection.IMvcBuilder AddOData (Microsoft.Extensions.DependencyInjection.IMvcBuilder builder, System.Action`2[[Microsoft.AspNetCore.OData.ODataOptions],[System.IServiceProvider]] setupAction) +} + +[ +ExtensionAttribute(), +] +public sealed class Microsoft.AspNetCore.OData.ODataMvcCoreBuilderExtensions { + [ + ExtensionAttribute(), + ] + public static Microsoft.Extensions.DependencyInjection.IMvcCoreBuilder AddOData (Microsoft.Extensions.DependencyInjection.IMvcCoreBuilder builder) + + [ + ExtensionAttribute(), + ] + public static Microsoft.Extensions.DependencyInjection.IMvcCoreBuilder AddOData (Microsoft.Extensions.DependencyInjection.IMvcCoreBuilder builder, System.Action`1[[Microsoft.AspNetCore.OData.ODataOptions]] setupAction) + + [ + ExtensionAttribute(), + ] + public static Microsoft.Extensions.DependencyInjection.IMvcCoreBuilder AddOData (Microsoft.Extensions.DependencyInjection.IMvcCoreBuilder builder, System.Action`2[[Microsoft.AspNetCore.OData.ODataOptions],[System.IServiceProvider]] setupAction) +} + +[ +ExtensionAttribute(), +] +public sealed class Microsoft.AspNetCore.OData.ODataServiceCollectionExtensions { + [ + ExtensionAttribute(), + ] + public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddODataQueryFilter (Microsoft.Extensions.DependencyInjection.IServiceCollection services) + + [ + ExtensionAttribute(), + ] + public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddODataQueryFilter (Microsoft.Extensions.DependencyInjection.IServiceCollection services, Microsoft.AspNetCore.Mvc.Filters.IActionFilter queryFilter) +} + +public sealed class Microsoft.AspNetCore.OData.ODataUriFunctions { + public static void AddCustomUriFunction (string functionName, Microsoft.OData.UriParser.FunctionSignatureWithReturnType functionSignature, System.Reflection.MethodInfo methodInfo) + public static bool RemoveCustomUriFunction (string functionName, Microsoft.OData.UriParser.FunctionSignatureWithReturnType functionSignature, System.Reflection.MethodInfo methodInfo) +} + +public class Microsoft.AspNetCore.OData.ODataJsonOptionsSetup : IConfigureOptions`1 { + public ODataJsonOptionsSetup () + + public virtual void Configure (Microsoft.AspNetCore.Mvc.JsonOptions options) +} + +public class Microsoft.AspNetCore.OData.ODataMvcOptionsSetup : IConfigureOptions`1 { + public ODataMvcOptionsSetup () + + public virtual void Configure (Microsoft.AspNetCore.Mvc.MvcOptions options) +} + +public class Microsoft.AspNetCore.OData.ODataOptions { + public ODataOptions () + + System.Collections.Generic.IList`1[[Microsoft.AspNetCore.OData.Routing.Conventions.IODataControllerActionConvention]] Conventions { public get; } + bool EnableAttributeRouting { public get; public set; } + bool EnableContinueOnErrorHeader { public get; public set; } + bool EnableNoDollarQueryOptions { public get; public set; } + Microsoft.OData.ModelBuilder.Config.DefaultQuerySettings QuerySettings { public get; } + [ + TupleElementNamesAttribute(), + ] + System.Collections.Generic.IDictionary`2[[System.String],[System.ValueTuple`2[[Microsoft.OData.Edm.IEdmModel],[System.IServiceProvider]]]] RouteComponents { public get; } + + Microsoft.AspNetCore.OData.Routing.ODataRouteOptions RouteOptions { public get; } + System.TimeZoneInfo TimeZone { public get; public set; } + Microsoft.OData.ODataUrlKeyDelimiter UrlKeyDelimiter { public get; public set; } + + public Microsoft.AspNetCore.OData.ODataOptions AddRouteComponents (Microsoft.OData.Edm.IEdmModel model) + public Microsoft.AspNetCore.OData.ODataOptions AddRouteComponents (Microsoft.OData.Edm.IEdmModel model, Microsoft.AspNetCore.OData.Batch.ODataBatchHandler batchHandler) + public Microsoft.AspNetCore.OData.ODataOptions AddRouteComponents (string routePrefix, Microsoft.OData.Edm.IEdmModel model) + public Microsoft.AspNetCore.OData.ODataOptions AddRouteComponents (string routePrefix, Microsoft.OData.Edm.IEdmModel model, Microsoft.AspNetCore.OData.Batch.ODataBatchHandler batchHandler) + public Microsoft.AspNetCore.OData.ODataOptions AddRouteComponents (string routePrefix, Microsoft.OData.Edm.IEdmModel model, System.Action`1[[Microsoft.Extensions.DependencyInjection.IServiceCollection]] configureServices) + public Microsoft.AspNetCore.OData.ODataOptions Count () + public Microsoft.AspNetCore.OData.ODataOptions EnableQueryFeatures (params System.Nullable`1[[System.Int32]] maxTopValue) + public Microsoft.AspNetCore.OData.ODataOptions Expand () + public Microsoft.AspNetCore.OData.ODataOptions Filter () + public System.IServiceProvider GetRouteServices (string routePrefix) + public Microsoft.AspNetCore.OData.ODataOptions OrderBy () + public Microsoft.AspNetCore.OData.ODataOptions Select () + public Microsoft.AspNetCore.OData.ODataOptions SetMaxTop (System.Nullable`1[[System.Int32]] maxTopValue) + public Microsoft.AspNetCore.OData.ODataOptions SkipToken () +} + +public class Microsoft.AspNetCore.OData.ODataOptionsSetup : IConfigureOptions`1 { + public ODataOptionsSetup (Microsoft.Extensions.Logging.ILoggerFactory loggerFactory, Microsoft.AspNetCore.OData.Routing.Parser.IODataPathTemplateParser parser) + + public virtual void Configure (Microsoft.AspNetCore.OData.ODataOptions options) +} + +public interface Microsoft.AspNetCore.OData.Abstracts.IETagHandler { + Microsoft.Net.Http.Headers.EntityTagHeaderValue CreateETag (System.Collections.Generic.IDictionary`2[[System.String],[System.Object]] properties, params System.TimeZoneInfo timeZoneInfo) + System.Collections.Generic.IDictionary`2[[System.String],[System.Object]] ParseETag (Microsoft.Net.Http.Headers.EntityTagHeaderValue etagHeaderValue) +} + +public interface Microsoft.AspNetCore.OData.Abstracts.IODataBatchFeature { + System.Nullable`1[[System.Guid]] BatchId { public abstract get; public abstract set; } + System.Nullable`1[[System.Guid]] ChangeSetId { public abstract get; public abstract set; } + string ContentId { public abstract get; public abstract set; } + System.Collections.Generic.IDictionary`2[[System.String],[System.String]] ContentIdMapping { public abstract get; } +} + +public interface Microsoft.AspNetCore.OData.Abstracts.IODataFeature { + Microsoft.OData.UriParser.Aggregation.ApplyClause ApplyClause { public abstract get; public abstract set; } + string BaseAddress { public abstract get; public abstract set; } + Microsoft.AspNetCore.Routing.RouteValueDictionary BatchRouteData { public abstract get; } + System.Uri DeltaLink { public abstract get; public abstract set; } + System.Net.EndPoint Endpoint { public abstract get; public abstract set; } + Microsoft.OData.Edm.IEdmModel Model { public abstract get; public abstract set; } + System.Uri NextLink { public abstract get; public abstract set; } + Microsoft.OData.UriParser.ODataPath Path { public abstract get; public abstract set; } + Microsoft.Extensions.DependencyInjection.IServiceScope RequestScope { public abstract get; public abstract set; } + string RoutePrefix { public abstract get; public abstract set; } + System.Collections.Generic.IDictionary`2[[System.String],[System.Object]] RoutingConventionsStore { public abstract get; } + Microsoft.OData.UriParser.SelectExpandClause SelectExpandClause { public abstract get; public abstract set; } + System.IServiceProvider Services { public abstract get; public abstract set; } + System.Nullable`1[[System.Int64]] TotalCount { public abstract get; public abstract set; } + System.Func`1[[System.Int64]] TotalCountFunc { public abstract get; public abstract set; } +} + +[ +AttributeUsageAttribute(), +] +public class Microsoft.AspNetCore.OData.Abstracts.ETagActionFilterAttribute : Microsoft.AspNetCore.Mvc.Filters.ActionFilterAttribute, IActionFilter, IAsyncActionFilter, IAsyncResultFilter, IFilterMetadata, IOrderedFilter, IResultFilter { + public ETagActionFilterAttribute () + + public virtual void OnActionExecuted (Microsoft.AspNetCore.Mvc.Filters.ActionExecutedContext actionExecutedContext) +} + +public class Microsoft.AspNetCore.OData.Abstracts.HttpRequestScope { + public HttpRequestScope () + + Microsoft.AspNetCore.Http.HttpRequest HttpRequest { public get; public set; } +} + +[ +AttributeUsageAttribute(), +] +public class Microsoft.AspNetCore.OData.Abstracts.NonValidatingParameterBindingAttribute : Microsoft.AspNetCore.Mvc.ModelBinderAttribute, IBinderTypeProviderMetadata, IBindingSourceMetadata, IModelNameProvider, IPropertyValidationFilter { + public NonValidatingParameterBindingAttribute () + + Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource BindingSource { public virtual get; } + + public virtual bool ShouldValidateEntry (Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationEntry entry, Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationEntry parentEntry) +} + +public class Microsoft.AspNetCore.OData.Abstracts.ODataBatchFeature : IODataBatchFeature { + public ODataBatchFeature () + + System.Nullable`1[[System.Guid]] BatchId { public virtual get; public virtual set; } + System.Nullable`1[[System.Guid]] ChangeSetId { public virtual get; public virtual set; } + string ContentId { public virtual get; public virtual set; } + System.Collections.Generic.IDictionary`2[[System.String],[System.String]] ContentIdMapping { public virtual get; } +} + +public class Microsoft.AspNetCore.OData.Abstracts.ODataFeature : IODataFeature { + public ODataFeature () + + Microsoft.OData.UriParser.Aggregation.ApplyClause ApplyClause { public virtual get; public virtual set; } + string BaseAddress { public virtual get; public virtual set; } + Microsoft.AspNetCore.Routing.RouteValueDictionary BatchRouteData { public virtual get; } + System.Uri DeltaLink { public virtual get; public virtual set; } + System.Net.EndPoint Endpoint { public virtual get; public virtual set; } + Microsoft.OData.Edm.IEdmModel Model { public virtual get; public virtual set; } + System.Uri NextLink { public virtual get; public virtual set; } + Microsoft.OData.UriParser.ODataPath Path { public virtual get; public virtual set; } + Microsoft.Extensions.DependencyInjection.IServiceScope RequestScope { public virtual get; public virtual set; } + string RoutePrefix { public virtual get; public virtual set; } + System.Collections.Generic.IDictionary`2[[System.String],[System.Object]] RoutingConventionsStore { public virtual get; } + Microsoft.OData.UriParser.SelectExpandClause SelectExpandClause { public virtual get; public virtual set; } + System.IServiceProvider Services { public virtual get; public virtual set; } + System.Nullable`1[[System.Int64]] TotalCount { public virtual get; public virtual set; } + System.Func`1[[System.Int64]] TotalCountFunc { public virtual get; public virtual set; } +} + +public abstract class Microsoft.AspNetCore.OData.Batch.ODataBatchHandler { + protected ODataBatchHandler () + + Microsoft.OData.ODataMessageQuotas MessageQuotas { public get; } + string PrefixName { public get; public set; } + + public virtual System.Threading.Tasks.Task CreateResponseMessageAsync (System.Collections.Generic.IEnumerable`1[[Microsoft.AspNetCore.OData.Batch.ODataBatchResponseItem]] responses, Microsoft.AspNetCore.Http.HttpRequest request) + public virtual System.Uri GetBaseUri (Microsoft.AspNetCore.Http.HttpRequest request) + public abstract System.Threading.Tasks.Task ProcessBatchAsync (Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Http.RequestDelegate nextHandler) + public virtual System.Threading.Tasks.Task`1[[System.Boolean]] ValidateRequest (Microsoft.AspNetCore.Http.HttpRequest request) +} + +public abstract class Microsoft.AspNetCore.OData.Batch.ODataBatchRequestItem { + protected ODataBatchRequestItem () + + System.Collections.Generic.IDictionary`2[[System.String],[System.String]] ContentIdToLocationMapping { public get; public set; } + + public abstract System.Threading.Tasks.Task`1[[Microsoft.AspNetCore.OData.Batch.ODataBatchResponseItem]] SendRequestAsync (Microsoft.AspNetCore.Http.RequestDelegate handler) + [ + AsyncStateMachineAttribute(), + ] + public static System.Threading.Tasks.Task SendRequestAsync (Microsoft.AspNetCore.Http.RequestDelegate handler, Microsoft.AspNetCore.Http.HttpContext context, System.Collections.Generic.IDictionary`2[[System.String],[System.String]] contentIdToLocationMapping) +} + +public abstract class Microsoft.AspNetCore.OData.Batch.ODataBatchResponseItem { + protected ODataBatchResponseItem () + + internal abstract bool IsResponseSuccessful () + [ + AsyncStateMachineAttribute(), + ] + public static System.Threading.Tasks.Task WriteMessageAsync (Microsoft.OData.ODataBatchWriter writer, Microsoft.AspNetCore.Http.HttpContext context) + + public abstract System.Threading.Tasks.Task WriteResponseAsync (Microsoft.OData.ODataBatchWriter writer) +} + +[ +EditorBrowsableAttribute(), +ExtensionAttribute(), +] +public sealed class Microsoft.AspNetCore.OData.Batch.HttpRequestExtensions { + [ + ExtensionAttribute(), + ] + public static void CopyAbsoluteUrl (Microsoft.AspNetCore.Http.HttpRequest request, System.Uri uri) + + [ + ExtensionAttribute(), + ] + public static Microsoft.OData.ODataMessageReader GetODataMessageReader (Microsoft.AspNetCore.Http.HttpRequest request, System.IServiceProvider requestContainer) +} + +[ +EditorBrowsableAttribute(), +ExtensionAttribute(), +] +public sealed class Microsoft.AspNetCore.OData.Batch.ODataBatchHttpRequestExtensions { + [ + ExtensionAttribute(), + ] + public static System.Nullable`1[[System.Guid]] GetODataBatchId (Microsoft.AspNetCore.Http.HttpRequest request) + + [ + ExtensionAttribute(), + ] + public static System.Nullable`1[[System.Guid]] GetODataChangeSetId (Microsoft.AspNetCore.Http.HttpRequest request) + + [ + ExtensionAttribute(), + ] + public static string GetODataContentId (Microsoft.AspNetCore.Http.HttpRequest request) + + [ + ExtensionAttribute(), + ] + public static System.Collections.Generic.IDictionary`2[[System.String],[System.String]] GetODataContentIdMapping (Microsoft.AspNetCore.Http.HttpRequest request) + + [ + ExtensionAttribute(), + ] + public static bool IsODataBatchRequest (Microsoft.AspNetCore.Http.HttpRequest request) + + [ + ExtensionAttribute(), + ] + public static void SetODataBatchId (Microsoft.AspNetCore.Http.HttpRequest request, System.Guid batchId) + + [ + ExtensionAttribute(), + ] + public static void SetODataChangeSetId (Microsoft.AspNetCore.Http.HttpRequest request, System.Guid changeSetId) + + [ + ExtensionAttribute(), + ] + public static void SetODataContentId (Microsoft.AspNetCore.Http.HttpRequest request, string contentId) + + [ + ExtensionAttribute(), + ] + public static void SetODataContentIdMapping (Microsoft.AspNetCore.Http.HttpRequest request, System.Collections.Generic.IDictionary`2[[System.String],[System.String]] contentIdMapping) +} + +[ +EditorBrowsableAttribute(), +ExtensionAttribute(), +] +public sealed class Microsoft.AspNetCore.OData.Batch.ODataBatchReaderExtensions { + [ + ExtensionAttribute(), + ] + public static System.Threading.Tasks.Task`1[[Microsoft.AspNetCore.Http.HttpContext]] ReadChangeSetOperationRequestAsync (Microsoft.OData.ODataBatchReader reader, Microsoft.AspNetCore.Http.HttpContext context, System.Guid batchId, System.Guid changeSetId, System.Threading.CancellationToken cancellationToken) + + [ + AsyncStateMachineAttribute(), + ExtensionAttribute(), + ] + public static System.Threading.Tasks.Task`1[[System.Collections.Generic.IList`1[[Microsoft.AspNetCore.Http.HttpContext]]]] ReadChangeSetRequestAsync (Microsoft.OData.ODataBatchReader reader, Microsoft.AspNetCore.Http.HttpContext context, System.Guid batchId, System.Threading.CancellationToken cancellationToken) + + [ + ExtensionAttribute(), + ] + public static System.Threading.Tasks.Task`1[[Microsoft.AspNetCore.Http.HttpContext]] ReadOperationRequestAsync (Microsoft.OData.ODataBatchReader reader, Microsoft.AspNetCore.Http.HttpContext context, System.Guid batchId, System.Threading.CancellationToken cancellationToken) +} + +public class Microsoft.AspNetCore.OData.Batch.ChangeSetRequestItem : Microsoft.AspNetCore.OData.Batch.ODataBatchRequestItem { + public ChangeSetRequestItem (System.Collections.Generic.IEnumerable`1[[Microsoft.AspNetCore.Http.HttpContext]] contexts) + + System.Collections.Generic.IEnumerable`1[[Microsoft.AspNetCore.Http.HttpContext]] Contexts { public get; } + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task`1[[Microsoft.AspNetCore.OData.Batch.ODataBatchResponseItem]] SendRequestAsync (Microsoft.AspNetCore.Http.RequestDelegate handler) +} + +public class Microsoft.AspNetCore.OData.Batch.ChangeSetResponseItem : Microsoft.AspNetCore.OData.Batch.ODataBatchResponseItem { + public ChangeSetResponseItem (System.Collections.Generic.IEnumerable`1[[Microsoft.AspNetCore.Http.HttpContext]] contexts) + + System.Collections.Generic.IEnumerable`1[[Microsoft.AspNetCore.Http.HttpContext]] Contexts { public get; } + + internal virtual bool IsResponseSuccessful () + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task WriteResponseAsync (Microsoft.OData.ODataBatchWriter writer) +} + +public class Microsoft.AspNetCore.OData.Batch.DefaultODataBatchHandler : Microsoft.AspNetCore.OData.Batch.ODataBatchHandler { + public DefaultODataBatchHandler () + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task`1[[System.Collections.Generic.IList`1[[Microsoft.AspNetCore.OData.Batch.ODataBatchResponseItem]]]] ExecuteRequestMessagesAsync (System.Collections.Generic.IEnumerable`1[[Microsoft.AspNetCore.OData.Batch.ODataBatchRequestItem]] requests, Microsoft.AspNetCore.Http.RequestDelegate handler) + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task`1[[System.Collections.Generic.IList`1[[Microsoft.AspNetCore.OData.Batch.ODataBatchRequestItem]]]] ParseBatchRequestsAsync (Microsoft.AspNetCore.Http.HttpContext context) + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task ProcessBatchAsync (Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Http.RequestDelegate nextHandler) +} + +public class Microsoft.AspNetCore.OData.Batch.ODataBatchContent { + public ODataBatchContent (System.Collections.Generic.IEnumerable`1[[Microsoft.AspNetCore.OData.Batch.ODataBatchResponseItem]] responses, System.IServiceProvider requestContainer) + public ODataBatchContent (System.Collections.Generic.IEnumerable`1[[Microsoft.AspNetCore.OData.Batch.ODataBatchResponseItem]] responses, System.IServiceProvider requestContainer, string contentType) + + Microsoft.AspNetCore.Http.IHeaderDictionary Headers { public get; } + System.Collections.Generic.IEnumerable`1[[Microsoft.AspNetCore.OData.Batch.ODataBatchResponseItem]] Responses { public get; } + + public System.Threading.Tasks.Task SerializeToStreamAsync (System.IO.Stream stream) +} + +public class Microsoft.AspNetCore.OData.Batch.ODataBatchMiddleware { + public ODataBatchMiddleware (System.IServiceProvider serviceProvider, Microsoft.AspNetCore.Http.RequestDelegate next) + + [ + AsyncStateMachineAttribute(), + ] + public System.Threading.Tasks.Task Invoke (Microsoft.AspNetCore.Http.HttpContext context) +} + +public class Microsoft.AspNetCore.OData.Batch.OperationRequestItem : Microsoft.AspNetCore.OData.Batch.ODataBatchRequestItem { + public OperationRequestItem (Microsoft.AspNetCore.Http.HttpContext context) + + Microsoft.AspNetCore.Http.HttpContext Context { public get; } + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task`1[[Microsoft.AspNetCore.OData.Batch.ODataBatchResponseItem]] SendRequestAsync (Microsoft.AspNetCore.Http.RequestDelegate handler) +} + +public class Microsoft.AspNetCore.OData.Batch.OperationResponseItem : Microsoft.AspNetCore.OData.Batch.ODataBatchResponseItem { + public OperationResponseItem (Microsoft.AspNetCore.Http.HttpContext context) + + Microsoft.AspNetCore.Http.HttpContext Context { public get; } + + internal virtual bool IsResponseSuccessful () + public virtual System.Threading.Tasks.Task WriteResponseAsync (Microsoft.OData.ODataBatchWriter writer) +} + +public class Microsoft.AspNetCore.OData.Batch.UnbufferedODataBatchHandler : Microsoft.AspNetCore.OData.Batch.ODataBatchHandler { + public UnbufferedODataBatchHandler () + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task`1[[Microsoft.AspNetCore.OData.Batch.ODataBatchResponseItem]] ExecuteChangeSetAsync (Microsoft.OData.ODataBatchReader batchReader, System.Guid batchId, Microsoft.AspNetCore.Http.HttpRequest originalRequest, Microsoft.AspNetCore.Http.RequestDelegate handler) + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task`1[[Microsoft.AspNetCore.OData.Batch.ODataBatchResponseItem]] ExecuteOperationAsync (Microsoft.OData.ODataBatchReader batchReader, System.Guid batchId, Microsoft.AspNetCore.Http.HttpRequest originalRequest, Microsoft.AspNetCore.Http.RequestDelegate handler) + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task ProcessBatchAsync (Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Http.RequestDelegate nextHandler) +} + +public enum Microsoft.AspNetCore.OData.Deltas.DeltaItemKind : int { + DeletedResource = 1 + DeltaDeletedLink = 2 + DeltaLink = 3 + Resource = 0 + Unknown = 4 +} + +public interface Microsoft.AspNetCore.OData.Deltas.IDelta : IDeltaSetItem { + void Clear () + System.Collections.Generic.IEnumerable`1[[System.String]] GetChangedPropertyNames () + System.Collections.Generic.IEnumerable`1[[System.String]] GetUnchangedPropertyNames () + bool TryGetPropertyType (string name, out System.Type& type) + bool TryGetPropertyValue (string name, out System.Object& value) + bool TrySetPropertyValue (string name, object value) +} + +public interface Microsoft.AspNetCore.OData.Deltas.IDeltaDeletedResource : IDelta, IDeltaSetItem { + System.Uri Id { public abstract get; public abstract set; } + System.Nullable`1[[Microsoft.OData.DeltaDeletedEntryReason]] Reason { public abstract get; public abstract set; } +} + +public interface Microsoft.AspNetCore.OData.Deltas.IDeltaSet : IEnumerable, ICollection`1, IEnumerable`1 { +} + +public interface Microsoft.AspNetCore.OData.Deltas.IDeltaSetItem { + Microsoft.AspNetCore.OData.Deltas.DeltaItemKind Kind { public abstract get; } +} + +public interface Microsoft.AspNetCore.OData.Deltas.ITypedDelta { + System.Type ExpectedClrType { public abstract get; } + System.Type StructuredType { public abstract get; } +} + +public abstract class Microsoft.AspNetCore.OData.Deltas.Delta : System.Dynamic.DynamicObject, IDynamicMetaObjectProvider, IDelta, IDeltaSetItem { + protected Delta () + + Microsoft.AspNetCore.OData.Deltas.DeltaItemKind Kind { public abstract get; } + + public abstract void Clear () + public abstract System.Collections.Generic.IEnumerable`1[[System.String]] GetChangedPropertyNames () + public abstract System.Collections.Generic.IEnumerable`1[[System.String]] GetUnchangedPropertyNames () + public virtual bool TryGetMember (System.Dynamic.GetMemberBinder binder, out System.Object& result) + public abstract bool TryGetPropertyType (string name, out System.Type& type) + public abstract bool TryGetPropertyValue (string name, out System.Object& value) + public virtual bool TrySetMember (System.Dynamic.SetMemberBinder binder, object value) + public abstract bool TrySetPropertyValue (string name, object value) +} + +[ +NonValidatingParameterBindingAttribute(), +] +public class Microsoft.AspNetCore.OData.Deltas.Delta`1 : Microsoft.AspNetCore.OData.Deltas.Delta, IDynamicMetaObjectProvider, IDelta, IDeltaSetItem, ITypedDelta { + public Delta`1 () + public Delta`1 (System.Type structuralType) + public Delta`1 (System.Type structuralType, System.Collections.Generic.IEnumerable`1[[System.String]] updatableProperties) + public Delta`1 (System.Type structuralType, System.Collections.Generic.IEnumerable`1[[System.String]] updatableProperties, System.Reflection.PropertyInfo dynamicDictionaryPropertyInfo) + + System.Type ExpectedClrType { public virtual get; } + Microsoft.AspNetCore.OData.Deltas.DeltaItemKind Kind { public virtual get; } + System.Type StructuredType { public virtual get; } + System.Collections.Generic.IList`1[[System.String]] UpdatableProperties { public get; } + + public virtual void Clear () + public void CopyChangedValues (T original) + public void CopyUnchangedValues (T original) + public virtual System.Collections.Generic.IEnumerable`1[[System.String]] GetChangedPropertyNames () + public T GetInstance () + public virtual System.Collections.Generic.IEnumerable`1[[System.String]] GetUnchangedPropertyNames () + public void Patch (T original) + public void Put (T original) + public virtual bool TryGetPropertyType (string name, out System.Type& type) + public virtual bool TryGetPropertyValue (string name, out System.Object& value) + public virtual bool TrySetPropertyValue (string name, object value) +} + +public class Microsoft.AspNetCore.OData.Deltas.DeltaDeletedResource`1 : Delta`1, IDynamicMetaObjectProvider, IDelta, IDeltaDeletedResource, IDeltaSetItem, ITypedDelta { + public DeltaDeletedResource`1 () + public DeltaDeletedResource`1 (System.Type structuralType) + public DeltaDeletedResource`1 (System.Type structuralType, System.Collections.Generic.IEnumerable`1[[System.String]] updatableProperties) + public DeltaDeletedResource`1 (System.Type structuralType, System.Collections.Generic.IEnumerable`1[[System.String]] updatableProperties, System.Reflection.PropertyInfo dynamicDictionaryPropertyInfo) + + System.Uri Id { public virtual get; public virtual set; } + Microsoft.AspNetCore.OData.Deltas.DeltaItemKind Kind { public virtual get; } + System.Nullable`1[[Microsoft.OData.DeltaDeletedEntryReason]] Reason { public virtual get; public virtual set; } +} + +[ +NonValidatingParameterBindingAttribute(), +] +public class Microsoft.AspNetCore.OData.Deltas.DeltaSet`1 : System.Collections.ObjectModel.Collection`1[[Microsoft.AspNetCore.OData.Deltas.IDeltaSetItem]], ICollection, IEnumerable, IList, IDeltaSet, ITypedDelta, ICollection`1, IEnumerable`1, IList`1, IReadOnlyCollection`1, IReadOnlyList`1 { + public DeltaSet`1 () + + System.Type ExpectedClrType { public virtual get; } + System.Type StructuredType { public virtual get; } +} + +public interface Microsoft.AspNetCore.OData.Edm.IODataTypeMapper { + System.Type GetClrPrimitiveType (Microsoft.OData.Edm.IEdmPrimitiveType primitiveType, bool nullable) + System.Type GetClrType (Microsoft.OData.Edm.IEdmModel edmModel, Microsoft.OData.Edm.IEdmType edmType, bool nullable, Microsoft.OData.ModelBuilder.IAssemblyResolver assembliesResolver) + Microsoft.OData.Edm.IEdmPrimitiveTypeReference GetEdmPrimitiveType (System.Type clrType) + Microsoft.OData.Edm.IEdmTypeReference GetEdmTypeReference (Microsoft.OData.Edm.IEdmModel edmModel, System.Type clrType) +} + +[ +ExtensionAttribute(), +] +public sealed class Microsoft.AspNetCore.OData.Edm.EdmModelAnnotationExtensions { + [ + ExtensionAttribute(), + ] + public static System.Collections.Generic.IEnumerable`1[[System.Collections.Generic.IDictionary`2[[System.String],[Microsoft.OData.Edm.IEdmPathExpression]]]] GetAlternateKeys (Microsoft.OData.Edm.IEdmModel model, Microsoft.OData.Edm.IEdmEntityType entityType) + + [ + ExtensionAttribute(), + ] + public static Microsoft.OData.ModelBuilder.ClrEnumMemberAnnotation GetClrEnumMemberAnnotation (Microsoft.OData.Edm.IEdmModel edmModel, Microsoft.OData.Edm.IEdmEnumType enumType) + + [ + ExtensionAttribute(), + ] + public static string GetClrPropertyName (Microsoft.OData.Edm.IEdmModel edmModel, Microsoft.OData.Edm.IEdmProperty edmProperty) + + [ + ExtensionAttribute(), + ] + public static System.Collections.Generic.IEnumerable`1[[Microsoft.OData.Edm.IEdmStructuralProperty]] GetConcurrencyProperties (Microsoft.OData.Edm.IEdmModel model, Microsoft.OData.Edm.IEdmNavigationSource navigationSource) + + [ + ExtensionAttribute(), + ] + public static System.Reflection.PropertyInfo GetDynamicPropertyDictionary (Microsoft.OData.Edm.IEdmModel edmModel, Microsoft.OData.Edm.IEdmStructuredType edmType) + + [ + ExtensionAttribute(), + ] + public static string GetModelName (Microsoft.OData.Edm.IEdmModel model) + + [ + ExtensionAttribute(), + ] + public static Microsoft.AspNetCore.OData.Edm.IODataTypeMapper GetTypeMapper (Microsoft.OData.Edm.IEdmModel model) + + [ + ExtensionAttribute(), + ] + public static void SetModelName (Microsoft.OData.Edm.IEdmModel model, string name) + + [ + ExtensionAttribute(), + ] + public static void SetTypeMapper (Microsoft.OData.Edm.IEdmModel model, Microsoft.AspNetCore.OData.Edm.IODataTypeMapper mapper) +} + +[ +ExtensionAttribute(), +] +public sealed class Microsoft.AspNetCore.OData.Edm.EdmModelLinkBuilderExtensions { + [ + ExtensionAttribute(), + ] + public static Microsoft.AspNetCore.OData.Edm.NavigationSourceLinkBuilderAnnotation GetNavigationSourceLinkBuilder (Microsoft.OData.Edm.IEdmModel model, Microsoft.OData.Edm.IEdmNavigationSource navigationSource) + + [ + ExtensionAttribute(), + ] + public static Microsoft.AspNetCore.OData.Edm.OperationLinkBuilder GetOperationLinkBuilder (Microsoft.OData.Edm.IEdmModel model, Microsoft.OData.Edm.IEdmOperation operation) + + [ + ExtensionAttribute(), + ] + public static void HasEditLink (Microsoft.OData.Edm.IEdmModel model, Microsoft.OData.Edm.IEdmNavigationSource navigationSource, Microsoft.AspNetCore.OData.Edm.SelfLinkBuilder`1[[System.Uri]] editLinkBuilder) + + [ + ExtensionAttribute(), + ] + public static void HasIdLink (Microsoft.OData.Edm.IEdmModel model, Microsoft.OData.Edm.IEdmNavigationSource navigationSource, Microsoft.AspNetCore.OData.Edm.SelfLinkBuilder`1[[System.Uri]] idLinkBuilder) + + [ + ExtensionAttribute(), + ] + public static void HasNavigationPropertyLink (Microsoft.OData.Edm.IEdmModel model, Microsoft.OData.Edm.IEdmNavigationSource navigationSource, Microsoft.OData.Edm.IEdmNavigationProperty navigationProperty, Microsoft.AspNetCore.OData.Edm.NavigationLinkBuilder linkBuilder) + + [ + ExtensionAttribute(), + ] + public static void HasReadLink (Microsoft.OData.Edm.IEdmModel model, Microsoft.OData.Edm.IEdmNavigationSource navigationSource, Microsoft.AspNetCore.OData.Edm.SelfLinkBuilder`1[[System.Uri]] readLinkBuilder) + + [ + ExtensionAttribute(), + ] + public static void SetNavigationSourceLinkBuilder (Microsoft.OData.Edm.IEdmModel model, Microsoft.OData.Edm.IEdmNavigationSource navigationSource, Microsoft.AspNetCore.OData.Edm.NavigationSourceLinkBuilderAnnotation navigationSourceLinkBuilder) + + [ + ExtensionAttribute(), + ] + public static void SetOperationLinkBuilder (Microsoft.OData.Edm.IEdmModel model, Microsoft.OData.Edm.IEdmOperation operation, Microsoft.AspNetCore.OData.Edm.OperationLinkBuilder operationLinkBuilder) +} + +[ +ExtensionAttribute(), +] +public sealed class Microsoft.AspNetCore.OData.Edm.IODataTypeMapperExtensions { + [ + ExtensionAttribute(), + ] + public static System.Type GetClrType (Microsoft.AspNetCore.OData.Edm.IODataTypeMapper mapper, Microsoft.OData.Edm.IEdmModel edmModel, Microsoft.OData.Edm.IEdmTypeReference edmType) + + [ + ExtensionAttribute(), + ] + public static System.Type GetClrType (Microsoft.AspNetCore.OData.Edm.IODataTypeMapper mapper, Microsoft.OData.Edm.IEdmModel edmModel, Microsoft.OData.Edm.IEdmTypeReference edmType, Microsoft.OData.ModelBuilder.IAssemblyResolver assembliesResolver) + + [ + ExtensionAttribute(), + ] + public static Microsoft.OData.Edm.IEdmType GetEdmType (Microsoft.AspNetCore.OData.Edm.IODataTypeMapper mapper, Microsoft.OData.Edm.IEdmModel edmModel, System.Type clrType) + + [ + ExtensionAttribute(), + ] + public static System.Type GetPrimitiveType (Microsoft.AspNetCore.OData.Edm.IODataTypeMapper mapper, Microsoft.OData.Edm.IEdmPrimitiveTypeReference primitiveType) +} + +public class Microsoft.AspNetCore.OData.Edm.CustomAggregateMethodAnnotation { + public CustomAggregateMethodAnnotation () + + public Microsoft.AspNetCore.OData.Edm.CustomAggregateMethodAnnotation AddMethod (string methodToken, System.Collections.Generic.IDictionary`2[[System.Type],[System.Reflection.MethodInfo]] methods) + public bool GetMethodInfo (string methodToken, System.Type returnType, out System.Reflection.MethodInfo& methodInfo) +} + +public class Microsoft.AspNetCore.OData.Edm.DefaultODataTypeMapper : IODataTypeMapper { + public DefaultODataTypeMapper () + + public virtual System.Type GetClrPrimitiveType (Microsoft.OData.Edm.IEdmPrimitiveType primitiveType, bool nullable) + public virtual System.Type GetClrType (Microsoft.OData.Edm.IEdmModel edmModel, Microsoft.OData.Edm.IEdmType edmType, bool nullable, Microsoft.OData.ModelBuilder.IAssemblyResolver assembliesResolver) + public virtual Microsoft.OData.Edm.IEdmPrimitiveTypeReference GetEdmPrimitiveType (System.Type clrType) + public virtual Microsoft.OData.Edm.IEdmTypeReference GetEdmTypeReference (Microsoft.OData.Edm.IEdmModel edmModel, System.Type clrType) +} + +public class Microsoft.AspNetCore.OData.Edm.EntitySelfLinks { + public EntitySelfLinks () + + System.Uri EditLink { public get; public set; } + System.Uri IdLink { public get; public set; } + System.Uri ReadLink { public get; public set; } +} + +public class Microsoft.AspNetCore.OData.Edm.ModelNameAnnotation { + public ModelNameAnnotation (string name) + + string ModelName { public get; } +} + +public class Microsoft.AspNetCore.OData.Edm.NavigationLinkBuilder { + public NavigationLinkBuilder (System.Func`3[[Microsoft.AspNetCore.OData.Formatter.ResourceContext],[Microsoft.OData.Edm.IEdmNavigationProperty],[System.Uri]] navigationLinkFactory, bool followsConventions) + + System.Func`3[[Microsoft.AspNetCore.OData.Formatter.ResourceContext],[Microsoft.OData.Edm.IEdmNavigationProperty],[System.Uri]] Factory { public get; } + bool FollowsConventions { public get; } +} + +public class Microsoft.AspNetCore.OData.Edm.NavigationSourceLinkBuilderAnnotation { + public NavigationSourceLinkBuilderAnnotation () + public NavigationSourceLinkBuilderAnnotation (Microsoft.OData.Edm.IEdmNavigationSource navigationSource, Microsoft.OData.Edm.IEdmModel model) + + Microsoft.AspNetCore.OData.Edm.SelfLinkBuilder`1[[System.Uri]] EditLinkBuilder { public get; public set; } + Microsoft.AspNetCore.OData.Edm.SelfLinkBuilder`1[[System.Uri]] IdLinkBuilder { public get; public set; } + Microsoft.AspNetCore.OData.Edm.SelfLinkBuilder`1[[System.Uri]] ReadLinkBuilder { public get; public set; } + + public void AddNavigationPropertyLinkBuilder (Microsoft.OData.Edm.IEdmNavigationProperty navigationProperty, Microsoft.AspNetCore.OData.Edm.NavigationLinkBuilder linkBuilder) + public virtual System.Uri BuildEditLink (Microsoft.AspNetCore.OData.Formatter.ResourceContext instanceContext, Microsoft.AspNetCore.OData.Formatter.ODataMetadataLevel metadataLevel, System.Uri idLink) + public virtual Microsoft.AspNetCore.OData.Edm.EntitySelfLinks BuildEntitySelfLinks (Microsoft.AspNetCore.OData.Formatter.ResourceContext instanceContext, Microsoft.AspNetCore.OData.Formatter.ODataMetadataLevel metadataLevel) + public virtual System.Uri BuildIdLink (Microsoft.AspNetCore.OData.Formatter.ResourceContext instanceContext, Microsoft.AspNetCore.OData.Formatter.ODataMetadataLevel metadataLevel) + public virtual System.Uri BuildNavigationLink (Microsoft.AspNetCore.OData.Formatter.ResourceContext instanceContext, Microsoft.OData.Edm.IEdmNavigationProperty navigationProperty, Microsoft.AspNetCore.OData.Formatter.ODataMetadataLevel metadataLevel) + public virtual System.Uri BuildReadLink (Microsoft.AspNetCore.OData.Formatter.ResourceContext instanceContext, Microsoft.AspNetCore.OData.Formatter.ODataMetadataLevel metadataLevel, System.Uri editLink) +} + +public class Microsoft.AspNetCore.OData.Edm.OperationLinkBuilder { + public OperationLinkBuilder (System.Func`2[[Microsoft.AspNetCore.OData.Formatter.ResourceContext],[System.Uri]] linkFactory, bool followsConventions) + public OperationLinkBuilder (System.Func`2[[Microsoft.AspNetCore.OData.Formatter.ResourceSetContext],[System.Uri]] linkFactory, bool followsConventions) + + bool FollowsConventions { public get; } + + public virtual System.Uri BuildLink (Microsoft.AspNetCore.OData.Formatter.ResourceContext context) + public virtual System.Uri BuildLink (Microsoft.AspNetCore.OData.Formatter.ResourceSetContext context) +} + +public class Microsoft.AspNetCore.OData.Edm.SelfLinkBuilder`1 { + public SelfLinkBuilder`1 (Func`2 linkFactory, bool followsConventions) + + Func`2 Factory { public get; } + bool FollowsConventions { public get; } +} + +[ +ExtensionAttribute(), +] +public sealed class Microsoft.AspNetCore.OData.Extensions.ActionModelExtensions { + [ + ExtensionAttribute(), + ] + public static void AddSelector (Microsoft.AspNetCore.Mvc.ApplicationModels.ActionModel action, string httpMethods, string prefix, Microsoft.OData.Edm.IEdmModel model, Microsoft.AspNetCore.OData.Routing.Template.ODataPathTemplate path, params Microsoft.AspNetCore.OData.Routing.ODataRouteOptions options) + + [ + ExtensionAttribute(), + ] + public static T GetAttribute (Microsoft.AspNetCore.Mvc.ApplicationModels.ActionModel action) + + [ + ExtensionAttribute(), + ] + public static bool HasODataKeyParameter (Microsoft.AspNetCore.Mvc.ApplicationModels.ActionModel action, Microsoft.OData.Edm.IEdmEntityType entityType, params bool enablePropertyNameCaseInsensitive, params string keyPrefix) + + [ + ExtensionAttribute(), + ] + public static bool HasParameter (Microsoft.AspNetCore.Mvc.ApplicationModels.ActionModel action, string parameterName) + + [ + ExtensionAttribute(), + ] + public static bool IsODataIgnored (Microsoft.AspNetCore.Mvc.ApplicationModels.ActionModel action) +} + +[ +ExtensionAttribute(), +] +public sealed class Microsoft.AspNetCore.OData.Extensions.ControllerModelExtensions { + [ + ExtensionAttribute(), + ] + public static T GetAttribute (Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerModel controller) + + [ + ExtensionAttribute(), + ] + public static bool HasAttribute (Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerModel controller) + + [ + ExtensionAttribute(), + ] + public static bool IsODataIgnored (Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerModel controller) +} + +[ +ExtensionAttribute(), +] +public sealed class Microsoft.AspNetCore.OData.Extensions.HttpContextExtensions { + [ + ExtensionAttribute(), + ] + public static Microsoft.AspNetCore.OData.Abstracts.IODataBatchFeature ODataBatchFeature (Microsoft.AspNetCore.Http.HttpContext httpContext) + + [ + ExtensionAttribute(), + ] + public static Microsoft.AspNetCore.OData.Abstracts.IODataFeature ODataFeature (Microsoft.AspNetCore.Http.HttpContext httpContext) + + [ + ExtensionAttribute(), + ] + public static Microsoft.AspNetCore.OData.ODataOptions ODataOptions (Microsoft.AspNetCore.Http.HttpContext httpContext) +} + +[ +ExtensionAttribute(), +] +public sealed class Microsoft.AspNetCore.OData.Extensions.HttpRequestExtensions { + [ + ExtensionAttribute(), + ] + public static void ClearRouteServices (Microsoft.AspNetCore.Http.HttpRequest request, params bool dispose) + + [ + ExtensionAttribute(), + ] + public static string CreateETag (Microsoft.AspNetCore.Http.HttpRequest request, System.Collections.Generic.IDictionary`2[[System.String],[System.Object]] properties, params System.TimeZoneInfo timeZone) + + [ + ExtensionAttribute(), + ] + public static System.IServiceProvider CreateRouteServices (Microsoft.AspNetCore.Http.HttpRequest request, string routePrefix) + + [ + ExtensionAttribute(), + ] + public static Microsoft.AspNetCore.OData.Formatter.Deserialization.IODataDeserializerProvider GetDeserializerProvider (Microsoft.AspNetCore.Http.HttpRequest request) + + [ + ExtensionAttribute(), + ] + public static Microsoft.AspNetCore.OData.Abstracts.IETagHandler GetETagHandler (Microsoft.AspNetCore.Http.HttpRequest request) + + [ + ExtensionAttribute(), + ] + public static Microsoft.OData.Edm.IEdmModel GetModel (Microsoft.AspNetCore.Http.HttpRequest request) + + [ + ExtensionAttribute(), + ] + public static System.Uri GetNextPageLink (Microsoft.AspNetCore.Http.HttpRequest request, int pageSize, object instance, System.Func`2[[System.Object],[System.String]] objectToSkipTokenValue) + + [ + ExtensionAttribute(), + ] + public static Microsoft.OData.ODataVersion GetODataVersion (Microsoft.AspNetCore.Http.HttpRequest request) + + [ + ExtensionAttribute(), + ] + public static Microsoft.OData.ODataMessageReaderSettings GetReaderSettings (Microsoft.AspNetCore.Http.HttpRequest request) + + [ + ExtensionAttribute(), + ] + public static System.IServiceProvider GetRouteServices (Microsoft.AspNetCore.Http.HttpRequest request) + + [ + ExtensionAttribute(), + ] + public static System.TimeZoneInfo GetTimeZoneInfo (Microsoft.AspNetCore.Http.HttpRequest request) + + [ + ExtensionAttribute(), + ] + public static Microsoft.OData.ODataMessageWriterSettings GetWriterSettings (Microsoft.AspNetCore.Http.HttpRequest request) + + [ + ExtensionAttribute(), + ] + public static bool IsCountRequest (Microsoft.AspNetCore.Http.HttpRequest request) + + [ + ExtensionAttribute(), + ] + public static bool IsNoDollarQueryEnable (Microsoft.AspNetCore.Http.HttpRequest request) + + [ + ExtensionAttribute(), + ] + public static Microsoft.AspNetCore.OData.Abstracts.IODataBatchFeature ODataBatchFeature (Microsoft.AspNetCore.Http.HttpRequest request) + + [ + ExtensionAttribute(), + ] + public static Microsoft.AspNetCore.OData.Abstracts.IODataFeature ODataFeature (Microsoft.AspNetCore.Http.HttpRequest request) + + [ + ExtensionAttribute(), + ] + public static Microsoft.AspNetCore.OData.ODataOptions ODataOptions (Microsoft.AspNetCore.Http.HttpRequest request) +} + +[ +ExtensionAttribute(), +] +public sealed class Microsoft.AspNetCore.OData.Extensions.HttpResponseExtensions { + [ + ExtensionAttribute(), + ] + public static bool IsSuccessStatusCode (Microsoft.AspNetCore.Http.HttpResponse response) +} + +[ +ExtensionAttribute(), +] +public sealed class Microsoft.AspNetCore.OData.Extensions.LinkGeneratorHelpers { + [ + ExtensionAttribute(), + ] + public static string CreateODataLink (Microsoft.AspNetCore.Http.HttpRequest request, Microsoft.OData.UriParser.ODataPathSegment[] segments) + + [ + ExtensionAttribute(), + ] + public static string CreateODataLink (Microsoft.AspNetCore.Http.HttpRequest request, System.Collections.Generic.IList`1[[Microsoft.OData.UriParser.ODataPathSegment]] segments) +} + +[ +EditorBrowsableAttribute(), +ExtensionAttribute(), +] +public sealed class Microsoft.AspNetCore.OData.Extensions.SerializableErrorExtensions { + [ + ExtensionAttribute(), + ] + public static Microsoft.OData.ODataError CreateODataError (Microsoft.AspNetCore.Mvc.SerializableError serializableError) +} + +public sealed class Microsoft.AspNetCore.OData.Extensions.SerializableErrorKeys { + public static readonly string ErrorCodeKey = "ErrorCode" + public static readonly string ExceptionMessageKey = "ExceptionMessage" + public static readonly string ExceptionTypeKey = "ExceptionType" + public static readonly string InnerExceptionKey = "InnerException" + public static readonly string MessageDetailKey = "MessageDetail" + public static readonly string MessageKey = "Message" + public static readonly string MessageLanguageKey = "MessageLanguage" + public static readonly string ModelStateKey = "ModelState" + public static readonly string StackTraceKey = "StackTrace" +} + +public enum Microsoft.AspNetCore.OData.Formatter.ODataMetadataLevel : int { + Full = 1 + Minimal = 0 + None = 2 +} + +[ +EditorBrowsableAttribute(), +ExtensionAttribute(), +] +public sealed class Microsoft.AspNetCore.OData.Formatter.LinkGenerationHelpers { + [ + ExtensionAttribute(), + ] + public static System.Uri GenerateActionLink (Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext, Microsoft.OData.Edm.IEdmOperation action) + + [ + ExtensionAttribute(), + ] + public static System.Uri GenerateActionLink (Microsoft.AspNetCore.OData.Formatter.ResourceSetContext resourceSetContext, Microsoft.OData.Edm.IEdmOperation action) + + [ + ExtensionAttribute(), + ] + public static System.Uri GenerateFunctionLink (Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext, Microsoft.OData.Edm.IEdmOperation function) + + [ + ExtensionAttribute(), + ] + public static System.Uri GenerateFunctionLink (Microsoft.AspNetCore.OData.Formatter.ResourceSetContext resourceSetContext, Microsoft.OData.Edm.IEdmOperation function) + + [ + ExtensionAttribute(), + ] + public static System.Uri GenerateNavigationPropertyLink (Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext, Microsoft.OData.Edm.IEdmNavigationProperty navigationProperty, bool includeCast) + + [ + ExtensionAttribute(), + ] + public static System.Uri GenerateSelfLink (Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext, bool includeCast) +} + +public sealed class Microsoft.AspNetCore.OData.Formatter.ODataInputFormatterFactory { + public static System.Collections.Generic.IList`1[[Microsoft.AspNetCore.OData.Formatter.ODataInputFormatter]] Create () +} + +[ +ExtensionAttribute(), +] +public sealed class Microsoft.AspNetCore.OData.Formatter.ODataOutputFormatterFactory { + public static System.Collections.Generic.IList`1[[Microsoft.AspNetCore.OData.Formatter.ODataOutputFormatter]] Create () +} + +[ +NonValidatingParameterBindingAttribute(), +] +public class Microsoft.AspNetCore.OData.Formatter.ODataActionParameters : System.Collections.Generic.Dictionary`2[[System.String],[System.Object]], ICollection, IDictionary, IEnumerable, IDeserializationCallback, ISerializable, IDictionary`2, IReadOnlyDictionary`2, ICollection`1, IEnumerable`1, IReadOnlyCollection`1 { + public ODataActionParameters () +} + +public class Microsoft.AspNetCore.OData.Formatter.ODataInputFormatter : Microsoft.AspNetCore.Mvc.Formatters.TextInputFormatter, IApiRequestFormatMetadataProvider, IInputFormatter { + public ODataInputFormatter (System.Collections.Generic.IEnumerable`1[[Microsoft.OData.ODataPayloadKind]] payloadKinds) + + System.Func`2[[Microsoft.AspNetCore.Http.HttpRequest],[System.Uri]] BaseAddressFactory { public get; public set; } + + public virtual bool CanRead (Microsoft.AspNetCore.Mvc.Formatters.InputFormatterContext context) + public static System.Uri GetDefaultBaseAddress (Microsoft.AspNetCore.Http.HttpRequest request) + public virtual System.Collections.Generic.IReadOnlyList`1[[System.String]] GetSupportedContentTypes (string contentType, System.Type objectType) + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task`1[[Microsoft.AspNetCore.Mvc.Formatters.InputFormatterResult]] ReadRequestBodyAsync (Microsoft.AspNetCore.Mvc.Formatters.InputFormatterContext context, System.Text.Encoding encoding) +} + +public class Microsoft.AspNetCore.OData.Formatter.ODataOutputFormatter : Microsoft.AspNetCore.Mvc.Formatters.TextOutputFormatter, IApiResponseTypeMetadataProvider, IOutputFormatter, IMediaTypeMappingCollection { + public ODataOutputFormatter (System.Collections.Generic.IEnumerable`1[[Microsoft.OData.ODataPayloadKind]] payloadKinds) + + System.Func`2[[Microsoft.AspNetCore.Http.HttpRequest],[System.Uri]] BaseAddressFactory { public get; public set; } + System.Collections.Generic.ICollection`1[[Microsoft.AspNetCore.OData.Formatter.MediaType.MediaTypeMapping]] MediaTypeMappings { public virtual get; } + + public virtual bool CanWriteResult (Microsoft.AspNetCore.Mvc.Formatters.OutputFormatterCanWriteContext context) + public static System.Uri GetDefaultBaseAddress (Microsoft.AspNetCore.Http.HttpRequest request) + public virtual System.Collections.Generic.IReadOnlyList`1[[System.String]] GetSupportedContentTypes (string contentType, System.Type objectType) + public virtual System.Threading.Tasks.Task WriteResponseBodyAsync (Microsoft.AspNetCore.Mvc.Formatters.OutputFormatterWriteContext context, System.Text.Encoding selectedEncoding) + public virtual void WriteResponseHeaders (Microsoft.AspNetCore.Mvc.Formatters.OutputFormatterWriteContext context) +} + +public class Microsoft.AspNetCore.OData.Formatter.ODataParameterValue { + public static string ParameterValuePrefix = "DF908045-6922-46A0-82F2-2F6E7F43D1B1_" + + public ODataParameterValue (object paramValue, Microsoft.OData.Edm.IEdmTypeReference paramType) + + Microsoft.OData.Edm.IEdmTypeReference EdmType { public get; } + object Value { public get; } +} + +[ +NonValidatingParameterBindingAttribute(), +] +public class Microsoft.AspNetCore.OData.Formatter.ODataUntypedActionParameters : System.Collections.Generic.Dictionary`2[[System.String],[System.Object]], ICollection, IDictionary, IEnumerable, IDeserializationCallback, ISerializable, IDictionary`2, IReadOnlyDictionary`2, ICollection`1, IEnumerable`1, IReadOnlyCollection`1 { + public ODataUntypedActionParameters (Microsoft.OData.Edm.IEdmAction action) + + Microsoft.OData.Edm.IEdmAction Action { public get; } +} + +public class Microsoft.AspNetCore.OData.Formatter.ResourceContext { + public ResourceContext () + public ResourceContext (Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext serializerContext, Microsoft.OData.Edm.IEdmStructuredTypeReference structuredType, object resourceInstance) + + System.Collections.Generic.IDictionary`2[[System.String],[System.Object]] DynamicComplexProperties { public get; public set; } + Microsoft.OData.Edm.IEdmModel EdmModel { public get; public set; } + Microsoft.AspNetCore.OData.Formatter.Value.IEdmStructuredObject EdmObject { public get; public set; } + Microsoft.OData.Edm.IEdmNavigationSource NavigationSource { public get; public set; } + Microsoft.AspNetCore.Http.HttpRequest Request { public get; public set; } + object ResourceInstance { public get; public set; } + Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext SerializerContext { public get; public set; } + bool SkipExpensiveAvailabilityChecks { public get; public set; } + Microsoft.OData.Edm.IEdmStructuredType StructuredType { public get; public set; } + + public object GetPropertyValue (string propertyName) +} + +public class Microsoft.AspNetCore.OData.Formatter.ResourceSetContext { + public ResourceSetContext () + + Microsoft.OData.Edm.IEdmModel EdmModel { public get; } + Microsoft.OData.Edm.IEdmEntitySetBase EntitySetBase { public get; public set; } + Microsoft.AspNetCore.Http.HttpRequest Request { public get; public set; } + object ResourceSetInstance { public get; public set; } +} + +[ +AttributeUsageAttribute(), +] +public sealed class Microsoft.AspNetCore.OData.Formatter.FromODataBodyAttribute : Microsoft.AspNetCore.Mvc.ModelBinderAttribute, IBinderTypeProviderMetadata, IBindingSourceMetadata, IModelNameProvider { + public FromODataBodyAttribute () +} + +[ +AttributeUsageAttribute(), +] +public sealed class Microsoft.AspNetCore.OData.Formatter.FromODataUriAttribute : Microsoft.AspNetCore.Mvc.ModelBinderAttribute, IBinderTypeProviderMetadata, IBindingSourceMetadata, IModelNameProvider { + public FromODataUriAttribute () +} + +[ +FlagsAttribute(), +] +public enum Microsoft.AspNetCore.OData.Query.AllowedArithmeticOperators : int { + Add = 1 + All = 31 + Divide = 8 + Modulo = 16 + Multiply = 4 + None = 0 + Subtract = 2 +} + +[ +FlagsAttribute(), +] +public enum Microsoft.AspNetCore.OData.Query.AllowedFunctions : int { + All = 268435456 + AllDateTimeFunctions = 7010304 + AllFunctions = 535494655 + AllMathFunctions = 58720256 + AllStringFunctions = 1023 + Any = 134217728 + Cast = 1024 + Ceiling = 33554432 + Concat = 32 + Contains = 4 + Date = 4096 + Day = 32768 + EndsWith = 2 + Floor = 16777216 + FractionalSeconds = 4194304 + Hour = 131072 + IndexOf = 16 + IsOf = 67108864 + Length = 8 + Minute = 524288 + Month = 8192 + None = 0 + Round = 8388608 + Second = 2097152 + StartsWith = 1 + Substring = 64 + Time = 16384 + ToLower = 128 + ToUpper = 256 + Trim = 512 + Year = 2048 +} + +[ +FlagsAttribute(), +] +public enum Microsoft.AspNetCore.OData.Query.AllowedLogicalOperators : int { + All = 1023 + And = 2 + Equal = 4 + GreaterThan = 16 + GreaterThanOrEqual = 32 + Has = 512 + LessThan = 64 + LessThanOrEqual = 128 + None = 0 + Not = 256 + NotEqual = 8 + Or = 1 +} + +[ +FlagsAttribute(), +] +public enum Microsoft.AspNetCore.OData.Query.AllowedQueryOptions : int { + All = 8191 + Apply = 1024 + Compute = 2048 + Count = 64 + DeltaToken = 512 + Expand = 2 + Filter = 1 + Format = 128 + None = 0 + OrderBy = 8 + Search = 4096 + Select = 4 + Skip = 32 + SkipToken = 256 + Supported = 7679 + Top = 16 +} + +public enum Microsoft.AspNetCore.OData.Query.HandleNullPropagationOption : int { + Default = 0 + False = 2 + True = 1 +} + +public interface Microsoft.AspNetCore.OData.Query.IODataQueryRequestParser { + bool CanParse (Microsoft.AspNetCore.Http.HttpRequest request) + System.Threading.Tasks.Task`1[[System.String]] ParseAsync (Microsoft.AspNetCore.Http.HttpRequest request) +} + +public abstract class Microsoft.AspNetCore.OData.Query.OrderByNode { + protected OrderByNode (Microsoft.OData.UriParser.OrderByClause orderByClause) + protected OrderByNode (Microsoft.OData.UriParser.OrderByDirection direction) + + Microsoft.OData.UriParser.OrderByDirection Direction { public get; } + + public static System.Collections.Generic.IList`1[[Microsoft.AspNetCore.OData.Query.OrderByNode]] CreateCollection (Microsoft.OData.UriParser.OrderByClause orderByClause) +} + +public abstract class Microsoft.AspNetCore.OData.Query.SkipTokenHandler { + protected SkipTokenHandler () + + public abstract IQueryable`1 ApplyTo (IQueryable`1 query, Microsoft.AspNetCore.OData.Query.SkipTokenQueryOption skipTokenQueryOption, Microsoft.AspNetCore.OData.Query.ODataQuerySettings querySettings, Microsoft.AspNetCore.OData.Query.ODataQueryOptions queryOptions) + public abstract System.Linq.IQueryable ApplyTo (System.Linq.IQueryable query, Microsoft.AspNetCore.OData.Query.SkipTokenQueryOption skipTokenQueryOption, Microsoft.AspNetCore.OData.Query.ODataQuerySettings querySettings, Microsoft.AspNetCore.OData.Query.ODataQueryOptions queryOptions) + public abstract System.Uri GenerateNextPageLink (System.Uri baseUri, int pageSize, object instance, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext context) +} + +[ +ExtensionAttribute(), +] +public sealed class Microsoft.AspNetCore.OData.Query.HttpRequestODataQueryExtensions { + [ + ExtensionAttribute(), + ] + public static Microsoft.AspNetCore.OData.Query.ETag GetETag (Microsoft.AspNetCore.Http.HttpRequest request, Microsoft.Net.Http.Headers.EntityTagHeaderValue entityTagHeaderValue) + + [ + ExtensionAttribute(), + ] + public static ETag`1 GetETag (Microsoft.AspNetCore.Http.HttpRequest request, Microsoft.Net.Http.Headers.EntityTagHeaderValue entityTagHeaderValue) +} + +public class Microsoft.AspNetCore.OData.Query.ApplyQueryOption { + public ApplyQueryOption (string rawValue, Microsoft.AspNetCore.OData.Query.ODataQueryContext context, Microsoft.OData.UriParser.ODataQueryOptionParser queryOptionParser) + + Microsoft.OData.UriParser.Aggregation.ApplyClause ApplyClause { public get; } + Microsoft.AspNetCore.OData.Query.ODataQueryContext Context { public get; } + string RawValue { public get; } + System.Type ResultClrType { public get; } + + public System.Linq.IQueryable ApplyTo (System.Linq.IQueryable query, Microsoft.AspNetCore.OData.Query.ODataQuerySettings querySettings) +} + +public class Microsoft.AspNetCore.OData.Query.ComputeQueryOption { + public ComputeQueryOption (string rawValue, Microsoft.AspNetCore.OData.Query.ODataQueryContext context, Microsoft.OData.UriParser.ODataQueryOptionParser queryOptionParser) + + Microsoft.OData.UriParser.ComputeClause ComputeClause { public get; } + Microsoft.AspNetCore.OData.Query.ODataQueryContext Context { public get; } + string RawValue { public get; } + System.Type ResultClrType { public get; } +} + +public class Microsoft.AspNetCore.OData.Query.CountQueryOption { + public CountQueryOption (string rawValue, Microsoft.AspNetCore.OData.Query.ODataQueryContext context, Microsoft.OData.UriParser.ODataQueryOptionParser queryOptionParser) + + Microsoft.AspNetCore.OData.Query.ODataQueryContext Context { public get; } + string RawValue { public get; } + Microsoft.AspNetCore.OData.Query.Validator.CountQueryValidator Validator { public get; public set; } + bool Value { public get; } + + public System.Nullable`1[[System.Int64]] GetEntityCount (System.Linq.IQueryable query) + public void Validate (Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings validationSettings) +} + +public class Microsoft.AspNetCore.OData.Query.DefaultODataQueryRequestParser : IODataQueryRequestParser { + public DefaultODataQueryRequestParser () + + public virtual bool CanParse (Microsoft.AspNetCore.Http.HttpRequest request) + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task`1[[System.String]] ParseAsync (Microsoft.AspNetCore.Http.HttpRequest request) +} + +public class Microsoft.AspNetCore.OData.Query.DefaultSkipTokenHandler : Microsoft.AspNetCore.OData.Query.SkipTokenHandler { + public DefaultSkipTokenHandler () + + public virtual IQueryable`1 ApplyTo (IQueryable`1 query, Microsoft.AspNetCore.OData.Query.SkipTokenQueryOption skipTokenQueryOption, Microsoft.AspNetCore.OData.Query.ODataQuerySettings querySettings, Microsoft.AspNetCore.OData.Query.ODataQueryOptions queryOptions) + public virtual System.Linq.IQueryable ApplyTo (System.Linq.IQueryable query, Microsoft.AspNetCore.OData.Query.SkipTokenQueryOption skipTokenQueryOption, Microsoft.AspNetCore.OData.Query.ODataQuerySettings querySettings, Microsoft.AspNetCore.OData.Query.ODataQueryOptions queryOptions) + public virtual System.Uri GenerateNextPageLink (System.Uri baseUri, int pageSize, object instance, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext context) +} + +[ +AttributeUsageAttribute(), +] +public class Microsoft.AspNetCore.OData.Query.EnableQueryAttribute : Microsoft.AspNetCore.Mvc.Filters.ActionFilterAttribute, IActionFilter, IAsyncActionFilter, IAsyncResultFilter, IFilterMetadata, IOrderedFilter, IResultFilter { + public EnableQueryAttribute () + + Microsoft.AspNetCore.OData.Query.AllowedArithmeticOperators AllowedArithmeticOperators { public get; public set; } + Microsoft.AspNetCore.OData.Query.AllowedFunctions AllowedFunctions { public get; public set; } + Microsoft.AspNetCore.OData.Query.AllowedLogicalOperators AllowedLogicalOperators { public get; public set; } + string AllowedOrderByProperties { public get; public set; } + Microsoft.AspNetCore.OData.Query.AllowedQueryOptions AllowedQueryOptions { public get; public set; } + bool EnableConstantParameterization { public get; public set; } + bool EnableCorrelatedSubqueryBuffering { public get; public set; } + bool EnsureStableOrdering { public get; public set; } + Microsoft.AspNetCore.OData.Query.HandleNullPropagationOption HandleNullPropagation { public get; public set; } + bool HandleReferenceNavigationPropertyExpandFilter { public get; public set; } + int MaxAnyAllExpressionDepth { public get; public set; } + int MaxExpansionDepth { public get; public set; } + int MaxNodeCount { public get; public set; } + int MaxOrderByNodeCount { public get; public set; } + int MaxSkip { public get; public set; } + int MaxTop { public get; public set; } + int PageSize { public get; public set; } + + public virtual System.Linq.IQueryable ApplyQuery (System.Linq.IQueryable queryable, Microsoft.AspNetCore.OData.Query.ODataQueryOptions queryOptions) + public virtual object ApplyQuery (object entity, Microsoft.AspNetCore.OData.Query.ODataQueryOptions queryOptions) + public static Microsoft.AspNetCore.Mvc.SerializableError CreateErrorResponse (string message, params System.Exception exception) + public virtual Microsoft.OData.Edm.IEdmModel GetModel (System.Type elementClrType, Microsoft.AspNetCore.Http.HttpRequest request, Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor) + public virtual void OnActionExecuted (Microsoft.AspNetCore.Mvc.Filters.ActionExecutedContext actionExecutedContext) + public virtual void OnActionExecuting (Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext actionExecutingContext) + public virtual void ValidateQuery (Microsoft.AspNetCore.Http.HttpRequest request, Microsoft.AspNetCore.OData.Query.ODataQueryOptions queryOptions) +} + +[ +DefaultMemberAttribute(), +] +public class Microsoft.AspNetCore.OData.Query.ETag : System.Dynamic.DynamicObject, IDynamicMetaObjectProvider { + public ETag () + + System.Type EntityType { public get; public set; } + bool IsAny { public get; public set; } + bool IsIfNoneMatch { public get; public set; } + bool IsWellFormed { public get; public set; } + object Item [string key] { public get; public set; } + + public virtual System.Linq.IQueryable ApplyTo (System.Linq.IQueryable query) + public virtual bool TryGetMember (System.Dynamic.GetMemberBinder binder, out System.Object& result) + public virtual bool TrySetMember (System.Dynamic.SetMemberBinder binder, object value) +} + +public class Microsoft.AspNetCore.OData.Query.ETag`1 : Microsoft.AspNetCore.OData.Query.ETag, IDynamicMetaObjectProvider { + public ETag`1 () + + public IQueryable`1 ApplyTo (IQueryable`1 query) + public virtual System.Linq.IQueryable ApplyTo (System.Linq.IQueryable query) +} + +public class Microsoft.AspNetCore.OData.Query.FilterQueryOption { + public FilterQueryOption (string rawValue, Microsoft.AspNetCore.OData.Query.ODataQueryContext context, Microsoft.OData.UriParser.ODataQueryOptionParser queryOptionParser) + + Microsoft.AspNetCore.OData.Query.ComputeQueryOption Compute { public get; public set; } + Microsoft.AspNetCore.OData.Query.ODataQueryContext Context { public get; } + Microsoft.OData.UriParser.FilterClause FilterClause { public get; } + string RawValue { public get; } + Microsoft.AspNetCore.OData.Query.Validator.FilterQueryValidator Validator { public get; public set; } + + public System.Linq.IQueryable ApplyTo (System.Linq.IQueryable query, Microsoft.AspNetCore.OData.Query.ODataQuerySettings querySettings) + public void Validate (Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings validationSettings) +} + +public class Microsoft.AspNetCore.OData.Query.ODataQueryContext { + public ODataQueryContext (Microsoft.OData.Edm.IEdmModel model, Microsoft.OData.Edm.IEdmType elementType, Microsoft.OData.UriParser.ODataPath path) + public ODataQueryContext (Microsoft.OData.Edm.IEdmModel model, System.Type elementClrType, Microsoft.OData.UriParser.ODataPath path) + + Microsoft.OData.ModelBuilder.Config.DefaultQuerySettings DefaultQuerySettings { public get; } + System.Type ElementClrType { public get; } + Microsoft.OData.Edm.IEdmType ElementType { public get; } + Microsoft.OData.Edm.IEdmModel Model { public get; } + Microsoft.OData.Edm.IEdmNavigationSource NavigationSource { public get; } + Microsoft.OData.UriParser.ODataPath Path { public get; } + System.IServiceProvider RequestContainer { public get; } +} + +[ +NonValidatingParameterBindingAttribute(), +ODataQueryParameterBindingAttribute(), +] +public class Microsoft.AspNetCore.OData.Query.ODataQueryOptions { + public ODataQueryOptions (Microsoft.AspNetCore.OData.Query.ODataQueryContext context, Microsoft.AspNetCore.Http.HttpRequest request) + + Microsoft.AspNetCore.OData.Query.ApplyQueryOption Apply { public get; } + Microsoft.AspNetCore.OData.Query.ComputeQueryOption Compute { public get; } + Microsoft.AspNetCore.OData.Query.ODataQueryContext Context { public get; } + Microsoft.AspNetCore.OData.Query.CountQueryOption Count { public get; } + Microsoft.AspNetCore.OData.Query.FilterQueryOption Filter { public get; } + Microsoft.AspNetCore.OData.Query.ETag IfMatch { public virtual get; } + Microsoft.AspNetCore.OData.Query.ETag IfNoneMatch { public virtual get; } + Microsoft.AspNetCore.OData.Query.OrderByQueryOption OrderBy { public get; } + Microsoft.AspNetCore.OData.Query.ODataRawQueryOptions RawValues { public get; } + Microsoft.AspNetCore.Http.HttpRequest Request { public get; } + Microsoft.AspNetCore.OData.Query.SearchQueryOption Search { public get; } + Microsoft.AspNetCore.OData.Query.SelectExpandQueryOption SelectExpand { public get; } + Microsoft.AspNetCore.OData.Query.SkipQueryOption Skip { public get; } + Microsoft.AspNetCore.OData.Query.SkipTokenQueryOption SkipToken { public get; } + Microsoft.AspNetCore.OData.Query.TopQueryOption Top { public get; } + Microsoft.AspNetCore.OData.Query.Validator.ODataQueryValidator Validator { public get; public set; } + + public virtual System.Linq.IQueryable ApplyTo (System.Linq.IQueryable query) + public virtual System.Linq.IQueryable ApplyTo (System.Linq.IQueryable query, Microsoft.AspNetCore.OData.Query.AllowedQueryOptions ignoreQueryOptions) + public virtual System.Linq.IQueryable ApplyTo (System.Linq.IQueryable query, Microsoft.AspNetCore.OData.Query.ODataQuerySettings querySettings) + public virtual object ApplyTo (object entity, Microsoft.AspNetCore.OData.Query.ODataQuerySettings querySettings) + public virtual System.Linq.IQueryable ApplyTo (System.Linq.IQueryable query, Microsoft.AspNetCore.OData.Query.ODataQuerySettings querySettings, Microsoft.AspNetCore.OData.Query.AllowedQueryOptions ignoreQueryOptions) + public virtual object ApplyTo (object entity, Microsoft.AspNetCore.OData.Query.ODataQuerySettings querySettings, Microsoft.AspNetCore.OData.Query.AllowedQueryOptions ignoreQueryOptions) + public virtual Microsoft.AspNetCore.OData.Query.OrderByQueryOption GenerateStableOrder () + internal virtual Microsoft.AspNetCore.OData.Query.ETag GetETag (Microsoft.Net.Http.Headers.EntityTagHeaderValue etagHeaderValue) + public bool IsSupportedQueryOption (string queryOptionName) + public static bool IsSystemQueryOption (string queryOptionName) + public static bool IsSystemQueryOption (string queryOptionName, bool isDollarSignOptional) + public static IQueryable`1 LimitResults (IQueryable`1 queryable, int limit, out System.Boolean& resultsLimited) + public static IQueryable`1 LimitResults (IQueryable`1 queryable, int limit, bool parameterize, out System.Boolean& resultsLimited) + public virtual void Validate (Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings validationSettings) +} + +[ +ODataQueryParameterBindingAttribute(), +] +public class Microsoft.AspNetCore.OData.Query.ODataQueryOptions`1 : Microsoft.AspNetCore.OData.Query.ODataQueryOptions { + public ODataQueryOptions`1 (Microsoft.AspNetCore.OData.Query.ODataQueryContext context, Microsoft.AspNetCore.Http.HttpRequest request) + + ETag`1 IfMatch { public get; } + ETag`1 IfNoneMatch { public get; } + + public virtual System.Linq.IQueryable ApplyTo (System.Linq.IQueryable query) + public virtual System.Linq.IQueryable ApplyTo (System.Linq.IQueryable query, Microsoft.AspNetCore.OData.Query.ODataQuerySettings querySettings) + internal virtual Microsoft.AspNetCore.OData.Query.ETag GetETag (Microsoft.Net.Http.Headers.EntityTagHeaderValue etagHeaderValue) +} + +public class Microsoft.AspNetCore.OData.Query.ODataQueryRequestMiddleware { + public ODataQueryRequestMiddleware (System.Collections.Generic.IEnumerable`1[[Microsoft.AspNetCore.OData.Query.IODataQueryRequestParser]] queryRequestParsers, Microsoft.AspNetCore.Http.RequestDelegate next) + + [ + AsyncStateMachineAttribute(), + ] + public System.Threading.Tasks.Task Invoke (Microsoft.AspNetCore.Http.HttpContext context) +} + +public class Microsoft.AspNetCore.OData.Query.ODataQuerySettings { + public ODataQuerySettings () + + bool EnableConstantParameterization { public get; public set; } + bool EnableCorrelatedSubqueryBuffering { public get; public set; } + bool EnsureStableOrdering { public get; public set; } + Microsoft.AspNetCore.OData.Query.HandleNullPropagationOption HandleNullPropagation { public get; public set; } + bool HandleReferenceNavigationPropertyExpandFilter { public get; public set; } + System.Nullable`1[[System.Int32]] PageSize { public get; public set; } + System.TimeZoneInfo TimeZone { public get; public set; } +} + +public class Microsoft.AspNetCore.OData.Query.ODataRawQueryOptions { + public ODataRawQueryOptions () + + string Apply { public get; } + string Compute { public get; } + string Count { public get; } + string DeltaToken { public get; } + string Expand { public get; } + string Filter { public get; } + string Format { public get; } + string OrderBy { public get; } + string Search { public get; } + string Select { public get; } + string Skip { public get; } + string SkipToken { public get; } + string Top { public get; } +} + +public class Microsoft.AspNetCore.OData.Query.OrderByCountNode : Microsoft.AspNetCore.OData.Query.OrderByNode { + public OrderByCountNode (Microsoft.OData.UriParser.OrderByClause orderByClause) + + Microsoft.OData.UriParser.OrderByClause OrderByClause { public get; } +} + +public class Microsoft.AspNetCore.OData.Query.OrderByItNode : Microsoft.AspNetCore.OData.Query.OrderByNode { + public OrderByItNode (Microsoft.OData.UriParser.OrderByDirection direction) +} + +public class Microsoft.AspNetCore.OData.Query.OrderByOpenPropertyNode : Microsoft.AspNetCore.OData.Query.OrderByNode { + public OrderByOpenPropertyNode (Microsoft.OData.UriParser.OrderByClause orderByClause) + + Microsoft.OData.UriParser.OrderByClause OrderByClause { public get; } + string PropertyName { public get; } +} + +public class Microsoft.AspNetCore.OData.Query.OrderByPropertyNode : Microsoft.AspNetCore.OData.Query.OrderByNode { + public OrderByPropertyNode (Microsoft.OData.UriParser.OrderByClause orderByClause) + public OrderByPropertyNode (Microsoft.OData.Edm.IEdmProperty property, Microsoft.OData.UriParser.OrderByDirection direction) + + Microsoft.OData.UriParser.OrderByClause OrderByClause { public get; } + Microsoft.OData.Edm.IEdmProperty Property { public get; } +} + +public class Microsoft.AspNetCore.OData.Query.OrderByQueryOption { + public OrderByQueryOption (string rawValue, Microsoft.AspNetCore.OData.Query.ODataQueryContext context, Microsoft.OData.UriParser.ODataQueryOptionParser queryOptionParser) + + Microsoft.AspNetCore.OData.Query.ComputeQueryOption Compute { public get; public set; } + Microsoft.AspNetCore.OData.Query.ODataQueryContext Context { public get; } + Microsoft.OData.UriParser.OrderByClause OrderByClause { public get; } + System.Collections.Generic.IList`1[[Microsoft.AspNetCore.OData.Query.OrderByNode]] OrderByNodes { public get; } + string RawValue { public get; } + Microsoft.AspNetCore.OData.Query.Validator.OrderByQueryValidator Validator { public get; public set; } + + public IOrderedQueryable`1 ApplyTo (IQueryable`1 query) + public System.Linq.IOrderedQueryable ApplyTo (System.Linq.IQueryable query) + public IOrderedQueryable`1 ApplyTo (IQueryable`1 query, Microsoft.AspNetCore.OData.Query.ODataQuerySettings querySettings) + public System.Linq.IOrderedQueryable ApplyTo (System.Linq.IQueryable query, Microsoft.AspNetCore.OData.Query.ODataQuerySettings querySettings) + public void Validate (Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings validationSettings) +} + +public class Microsoft.AspNetCore.OData.Query.QueryFilterProvider : IFilterProvider { + public QueryFilterProvider (Microsoft.AspNetCore.Mvc.Filters.IActionFilter queryFilter) + + int Order { public virtual get; } + Microsoft.AspNetCore.Mvc.Filters.IActionFilter QueryFilter { public get; } + + public virtual void OnProvidersExecuted (Microsoft.AspNetCore.Mvc.Filters.FilterProviderContext context) + public virtual void OnProvidersExecuting (Microsoft.AspNetCore.Mvc.Filters.FilterProviderContext context) +} + +public class Microsoft.AspNetCore.OData.Query.SearchQueryOption { + public SearchQueryOption (string rawValue, Microsoft.AspNetCore.OData.Query.ODataQueryContext context, Microsoft.OData.UriParser.ODataQueryOptionParser queryOptionParser) + + Microsoft.AspNetCore.OData.Query.ODataQueryContext Context { public get; } + string RawValue { public get; } + System.Type ResultClrType { public get; } + Microsoft.OData.UriParser.SearchClause SearchClause { public get; } + + public System.Linq.IQueryable ApplyTo (System.Linq.IQueryable query, Microsoft.AspNetCore.OData.Query.ODataQuerySettings querySettings) +} + +public class Microsoft.AspNetCore.OData.Query.SelectExpandQueryOption { + public SelectExpandQueryOption (string select, string expand, Microsoft.AspNetCore.OData.Query.ODataQueryContext context, Microsoft.OData.UriParser.ODataQueryOptionParser queryOptionParser) + + Microsoft.AspNetCore.OData.Query.ComputeQueryOption Compute { public get; public set; } + Microsoft.AspNetCore.OData.Query.ODataQueryContext Context { public get; } + int LevelsMaxLiteralExpansionDepth { public get; public set; } + string RawExpand { public get; } + string RawSelect { public get; } + Microsoft.OData.UriParser.SelectExpandClause SelectExpandClause { public get; } + Microsoft.AspNetCore.OData.Query.Validator.SelectExpandQueryValidator Validator { public get; public set; } + + public System.Linq.IQueryable ApplyTo (System.Linq.IQueryable queryable, Microsoft.AspNetCore.OData.Query.ODataQuerySettings settings) + public object ApplyTo (object entity, Microsoft.AspNetCore.OData.Query.ODataQuerySettings settings) + public void Validate (Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings validationSettings) +} + +public class Microsoft.AspNetCore.OData.Query.SkipQueryOption { + public SkipQueryOption (string rawValue, Microsoft.AspNetCore.OData.Query.ODataQueryContext context, Microsoft.OData.UriParser.ODataQueryOptionParser queryOptionParser) + + Microsoft.AspNetCore.OData.Query.ODataQueryContext Context { public get; } + string RawValue { public get; } + Microsoft.AspNetCore.OData.Query.Validator.SkipQueryValidator Validator { public get; public set; } + int Value { public get; } + + public IQueryable`1 ApplyTo (IQueryable`1 query, Microsoft.AspNetCore.OData.Query.ODataQuerySettings querySettings) + public System.Linq.IQueryable ApplyTo (System.Linq.IQueryable query, Microsoft.AspNetCore.OData.Query.ODataQuerySettings querySettings) + public void Validate (Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings validationSettings) +} + +public class Microsoft.AspNetCore.OData.Query.SkipTokenQueryOption { + public SkipTokenQueryOption (string rawValue, Microsoft.AspNetCore.OData.Query.ODataQueryContext context) + + Microsoft.AspNetCore.OData.Query.ODataQueryContext Context { public get; } + Microsoft.AspNetCore.OData.Query.SkipTokenHandler Handler { public get; } + string RawValue { public get; } + Microsoft.AspNetCore.OData.Query.Validator.SkipTokenQueryValidator Validator { public get; } + + public virtual IQueryable`1 ApplyTo (IQueryable`1 query, Microsoft.AspNetCore.OData.Query.ODataQuerySettings querySettings, Microsoft.AspNetCore.OData.Query.ODataQueryOptions queryOptions) + public virtual System.Linq.IQueryable ApplyTo (System.Linq.IQueryable query, Microsoft.AspNetCore.OData.Query.ODataQuerySettings querySettings, Microsoft.AspNetCore.OData.Query.ODataQueryOptions queryOptions) + public void Validate (Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings validationSettings) +} + +public class Microsoft.AspNetCore.OData.Query.TopQueryOption { + public TopQueryOption (string rawValue, Microsoft.AspNetCore.OData.Query.ODataQueryContext context, Microsoft.OData.UriParser.ODataQueryOptionParser queryOptionParser) + + Microsoft.AspNetCore.OData.Query.ODataQueryContext Context { public get; } + string RawValue { public get; } + Microsoft.AspNetCore.OData.Query.Validator.TopQueryValidator Validator { public get; public set; } + int Value { public get; } + + public IOrderedQueryable`1 ApplyTo (IQueryable`1 query, Microsoft.AspNetCore.OData.Query.ODataQuerySettings querySettings) + public System.Linq.IQueryable ApplyTo (System.Linq.IQueryable query, Microsoft.AspNetCore.OData.Query.ODataQuerySettings querySettings) + public void Validate (Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings validationSettings) +} + +[ +AttributeUsageAttribute(), +] +public sealed class Microsoft.AspNetCore.OData.Query.ODataQueryParameterBindingAttribute : Microsoft.AspNetCore.Mvc.ModelBinderAttribute, IBinderTypeProviderMetadata, IBindingSourceMetadata, IModelNameProvider { + public ODataQueryParameterBindingAttribute () +} + +public interface Microsoft.AspNetCore.OData.Results.IODataErrorResult { + Microsoft.OData.ODataError Error { public abstract get; } +} + +[ +DataContractAttribute(), +] +public abstract class Microsoft.AspNetCore.OData.Results.PageResult { + protected PageResult (System.Uri nextPageLink, System.Nullable`1[[System.Int64]] count) + + [ + DataMemberAttribute(), + ] + System.Nullable`1[[System.Int64]] Count { public get; } + + [ + DataMemberAttribute(), + ] + System.Uri NextPageLink { public get; } + + public abstract System.Collections.Generic.IDictionary`2[[System.String],[System.Object]] ToDictionary () +} + +public abstract class Microsoft.AspNetCore.OData.Results.SingleResult { + protected SingleResult (System.Linq.IQueryable queryable) + + System.Linq.IQueryable Queryable { public get; } + + public static SingleResult`1 Create (IQueryable`1 queryable) +} + +public class Microsoft.AspNetCore.OData.Results.BadRequestODataResult : Microsoft.AspNetCore.Mvc.BadRequestResult, IActionResult, IClientErrorActionResult, IStatusCodeActionResult, IODataErrorResult { + public BadRequestODataResult (Microsoft.OData.ODataError odataError) + public BadRequestODataResult (string message) + + Microsoft.OData.ODataError Error { public virtual get; } + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task ExecuteResultAsync (Microsoft.AspNetCore.Mvc.ActionContext context) +} + +public class Microsoft.AspNetCore.OData.Results.ConflictODataResult : Microsoft.AspNetCore.Mvc.ConflictResult, IActionResult, IClientErrorActionResult, IStatusCodeActionResult, IODataErrorResult { + public ConflictODataResult (Microsoft.OData.ODataError odataError) + public ConflictODataResult (string message) + + Microsoft.OData.ODataError Error { public virtual get; } + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task ExecuteResultAsync (Microsoft.AspNetCore.Mvc.ActionContext context) +} + +public class Microsoft.AspNetCore.OData.Results.CreatedODataResult`1 : Microsoft.AspNetCore.Mvc.ActionResult, IActionResult { + public CreatedODataResult`1 (T entity) + + T Entity { public virtual get; } + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task ExecuteResultAsync (Microsoft.AspNetCore.Mvc.ActionContext context) +} + +public class Microsoft.AspNetCore.OData.Results.NotFoundODataResult : Microsoft.AspNetCore.Mvc.NotFoundResult, IActionResult, IClientErrorActionResult, IStatusCodeActionResult, IODataErrorResult { + public NotFoundODataResult (Microsoft.OData.ODataError odataError) + public NotFoundODataResult (string message) + + Microsoft.OData.ODataError Error { public virtual get; } + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task ExecuteResultAsync (Microsoft.AspNetCore.Mvc.ActionContext context) +} + +public class Microsoft.AspNetCore.OData.Results.ODataErrorResult : Microsoft.AspNetCore.Mvc.ActionResult, IActionResult, IODataErrorResult { + public ODataErrorResult (Microsoft.OData.ODataError odataError) + public ODataErrorResult (string errorCode, string message) + + Microsoft.OData.ODataError Error { public virtual get; } + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task ExecuteResultAsync (Microsoft.AspNetCore.Mvc.ActionContext context) +} + +[ +DataContractAttribute(), +] +public class Microsoft.AspNetCore.OData.Results.PageResult`1 : Microsoft.AspNetCore.OData.Results.PageResult, IEnumerable`1, IEnumerable { + public PageResult`1 (IEnumerable`1 items, System.Uri nextPageLink, System.Nullable`1[[System.Int64]] count) + + [ + DataMemberAttribute(), + ] + IEnumerable`1 Items { public get; } + + public virtual IEnumerator`1 GetEnumerator () + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator () + public virtual System.Collections.Generic.IDictionary`2[[System.String],[System.Object]] ToDictionary () +} + +public class Microsoft.AspNetCore.OData.Results.UnauthorizedODataResult : Microsoft.AspNetCore.Mvc.UnauthorizedResult, IActionResult, IClientErrorActionResult, IStatusCodeActionResult, IODataErrorResult { + public UnauthorizedODataResult (Microsoft.OData.ODataError odataError) + public UnauthorizedODataResult (string message) + + Microsoft.OData.ODataError Error { public virtual get; } + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task ExecuteResultAsync (Microsoft.AspNetCore.Mvc.ActionContext context) +} + +public class Microsoft.AspNetCore.OData.Results.UnprocessableEntityODataResult : Microsoft.AspNetCore.Mvc.UnprocessableEntityResult, IActionResult, IClientErrorActionResult, IStatusCodeActionResult, IODataErrorResult { + public UnprocessableEntityODataResult (Microsoft.OData.ODataError odataError) + public UnprocessableEntityODataResult (string message) + + Microsoft.OData.ODataError Error { public virtual get; } + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task ExecuteResultAsync (Microsoft.AspNetCore.Mvc.ActionContext context) +} + +public class Microsoft.AspNetCore.OData.Results.UpdatedODataResult`1 : Microsoft.AspNetCore.Mvc.ActionResult, IActionResult { + public UpdatedODataResult`1 (T entity) + + T Entity { public virtual get; } + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task ExecuteResultAsync (Microsoft.AspNetCore.Mvc.ActionContext context) +} + +public sealed class Microsoft.AspNetCore.OData.Results.SingleResult`1 : Microsoft.AspNetCore.OData.Results.SingleResult { + public SingleResult`1 (IQueryable`1 queryable) + + IQueryable`1 Queryable { public get; } +} + +public interface Microsoft.AspNetCore.OData.Routing.IODataRoutingMetadata { + Microsoft.OData.Edm.IEdmModel Model { public abstract get; } + string Prefix { public abstract get; } + Microsoft.AspNetCore.OData.Routing.Template.ODataPathTemplate Template { public abstract get; } +} + +[ +ExtensionAttribute(), +] +public sealed class Microsoft.AspNetCore.OData.Routing.ODataPathExtensions { + [ + ExtensionAttribute(), + ] + public static Microsoft.OData.Edm.IEdmType GetEdmType (Microsoft.OData.UriParser.ODataPath path) + + [ + ExtensionAttribute(), + ] + public static Microsoft.OData.Edm.IEdmNavigationSource GetNavigationSource (Microsoft.OData.UriParser.ODataPath path) + + [ + ExtensionAttribute(), + ] + public static string GetPathString (Microsoft.OData.UriParser.ODataPath path) + + [ + ExtensionAttribute(), + ] + public static string GetPathString (System.Collections.Generic.IList`1[[Microsoft.OData.UriParser.ODataPathSegment]] segments) + + [ + ExtensionAttribute(), + ] + public static bool IsStreamPropertyPath (Microsoft.OData.UriParser.ODataPath path) +} + +public sealed class Microsoft.AspNetCore.OData.Routing.ODataSegmentKinds { + public static string Action = "action" + public static string Batch = "$batch" + public static string Cast = "cast" + public static string Count = "$count" + public static string DynamicProperty = "dynamicproperty" + public static string EntitySet = "entityset" + public static string Function = "function" + public static string Key = "key" + public static string Metadata = "$metadata" + public static string Navigation = "navigation" + public static string PathTemplate = "template" + public static string Property = "property" + public static string Ref = "$ref" + public static string ServiceBase = "~" + public static string Singleton = "singleton" + public static string UnboundAction = "unboundaction" + public static string UnboundFunction = "unboundfunction" + public static string Unresolved = "unresolved" + public static string Value = "$value" +} + +public class Microsoft.AspNetCore.OData.Routing.ODataPathNavigationSourceHandler : Microsoft.OData.UriParser.PathSegmentHandler { + public ODataPathNavigationSourceHandler () + + Microsoft.OData.Edm.IEdmNavigationSource NavigationSource { public get; } + string Path { public get; } + + public virtual void Handle (Microsoft.OData.UriParser.BatchSegment segment) + public virtual void Handle (Microsoft.OData.UriParser.CountSegment segment) + public virtual void Handle (Microsoft.OData.UriParser.DynamicPathSegment segment) + public virtual void Handle (Microsoft.OData.UriParser.EntitySetSegment segment) + public virtual void Handle (Microsoft.OData.UriParser.KeySegment segment) + public virtual void Handle (Microsoft.OData.UriParser.MetadataSegment segment) + public virtual void Handle (Microsoft.OData.UriParser.NavigationPropertyLinkSegment segment) + public virtual void Handle (Microsoft.OData.UriParser.NavigationPropertySegment segment) + public virtual void Handle (Microsoft.OData.UriParser.ODataPathSegment segment) + public virtual void Handle (Microsoft.OData.UriParser.OperationImportSegment segment) + public virtual void Handle (Microsoft.OData.UriParser.OperationSegment segment) + public virtual void Handle (Microsoft.OData.UriParser.PathTemplateSegment segment) + public virtual void Handle (Microsoft.OData.UriParser.PropertySegment segment) + public virtual void Handle (Microsoft.OData.UriParser.SingletonSegment segment) + public virtual void Handle (Microsoft.OData.UriParser.TypeSegment segment) + public virtual void Handle (Microsoft.OData.UriParser.ValueSegment segment) +} + +public class Microsoft.AspNetCore.OData.Routing.ODataPathSegmentHandler : Microsoft.OData.UriParser.PathSegmentHandler { + public ODataPathSegmentHandler () + + Microsoft.OData.Edm.IEdmNavigationSource NavigationSource { public get; } + string PathLiteral { public get; } + + public virtual void Handle (Microsoft.OData.UriParser.BatchSegment segment) + public virtual void Handle (Microsoft.OData.UriParser.CountSegment segment) + public virtual void Handle (Microsoft.OData.UriParser.DynamicPathSegment segment) + public virtual void Handle (Microsoft.OData.UriParser.EntitySetSegment segment) + public virtual void Handle (Microsoft.OData.UriParser.KeySegment segment) + public virtual void Handle (Microsoft.OData.UriParser.MetadataSegment segment) + public virtual void Handle (Microsoft.OData.UriParser.NavigationPropertyLinkSegment segment) + public virtual void Handle (Microsoft.OData.UriParser.NavigationPropertySegment segment) + public virtual void Handle (Microsoft.OData.UriParser.OperationImportSegment segment) + public virtual void Handle (Microsoft.OData.UriParser.OperationSegment segment) + public virtual void Handle (Microsoft.OData.UriParser.PathTemplateSegment segment) + public virtual void Handle (Microsoft.OData.UriParser.PropertySegment segment) + public virtual void Handle (Microsoft.OData.UriParser.SingletonSegment segment) + public virtual void Handle (Microsoft.OData.UriParser.TypeSegment segment) + public virtual void Handle (Microsoft.OData.UriParser.ValueSegment segment) +} + +public class Microsoft.AspNetCore.OData.Routing.ODataPathSegmentTranslator : Microsoft.OData.UriParser.PathSegmentTranslator`1[[Microsoft.OData.UriParser.ODataPathSegment]] { + public ODataPathSegmentTranslator () + + public static Microsoft.OData.UriParser.SingleValueNode TranslateParameterAlias (Microsoft.OData.UriParser.SingleValueNode node, System.Collections.Generic.IDictionary`2[[System.String],[Microsoft.OData.UriParser.SingleValueNode]] parameterAliasNodes) +} + +public class Microsoft.AspNetCore.OData.Routing.ODataRouteOptions { + public ODataRouteOptions () + + bool EnableActionNameCaseInsensitive { public get; public set; } + bool EnableControllerNameCaseInsensitive { public get; public set; } + bool EnableKeyAsSegment { public get; public set; } + bool EnableKeyInParenthesis { public get; public set; } + bool EnableNonParenthesisForEmptyParameterFunction { public get; public set; } + bool EnablePropertyNameCaseInsensitive { public get; public set; } + bool EnableQualifiedOperationCall { public get; public set; } + bool EnableUnqualifiedOperationCall { public get; public set; } +} + +public sealed class Microsoft.AspNetCore.OData.Routing.ODataRoutingMetadata : IODataRoutingMetadata { + public ODataRoutingMetadata (string prefix, Microsoft.OData.Edm.IEdmModel model, Microsoft.AspNetCore.OData.Routing.Template.ODataPathTemplate template) + + Microsoft.OData.Edm.IEdmModel Model { public virtual get; } + string Prefix { public virtual get; } + Microsoft.AspNetCore.OData.Routing.Template.ODataPathTemplate Template { public virtual get; } +} + +public interface Microsoft.AspNetCore.OData.Formatter.Deserialization.IODataDeserializer { + Microsoft.OData.ODataPayloadKind ODataPayloadKind { public abstract get; } + + System.Threading.Tasks.Task`1[[System.Object]] ReadAsync (Microsoft.OData.ODataMessageReader messageReader, System.Type type, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) +} + +public interface Microsoft.AspNetCore.OData.Formatter.Deserialization.IODataDeserializerProvider { + Microsoft.AspNetCore.OData.Formatter.Deserialization.IODataEdmTypeDeserializer GetEdmTypeDeserializer (Microsoft.OData.Edm.IEdmTypeReference edmType, params bool isDelta) + Microsoft.AspNetCore.OData.Formatter.Deserialization.IODataDeserializer GetODataDeserializer (System.Type type, Microsoft.AspNetCore.Http.HttpRequest request) +} + +public interface Microsoft.AspNetCore.OData.Formatter.Deserialization.IODataEdmTypeDeserializer : IODataDeserializer { + object ReadInline (object item, Microsoft.OData.Edm.IEdmTypeReference edmType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) +} + +public abstract class Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializer : IODataDeserializer { + protected ODataDeserializer (Microsoft.OData.ODataPayloadKind payloadKind) + + Microsoft.OData.ODataPayloadKind ODataPayloadKind { public virtual get; } + + public virtual System.Threading.Tasks.Task`1[[System.Object]] ReadAsync (Microsoft.OData.ODataMessageReader messageReader, System.Type type, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) +} + +public abstract class Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataEdmTypeDeserializer : Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializer, IODataDeserializer, IODataEdmTypeDeserializer { + protected ODataEdmTypeDeserializer (Microsoft.OData.ODataPayloadKind payloadKind) + protected ODataEdmTypeDeserializer (Microsoft.OData.ODataPayloadKind payloadKind, Microsoft.AspNetCore.OData.Formatter.Deserialization.IODataDeserializerProvider deserializerProvider) + + Microsoft.AspNetCore.OData.Formatter.Deserialization.IODataDeserializerProvider DeserializerProvider { public get; } + + public virtual object ReadInline (object item, Microsoft.OData.Edm.IEdmTypeReference edmType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) +} + +public class Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataActionPayloadDeserializer : Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializer, IODataDeserializer { + public ODataActionPayloadDeserializer (Microsoft.AspNetCore.OData.Formatter.Deserialization.IODataDeserializerProvider deserializerProvider) + + Microsoft.AspNetCore.OData.Formatter.Deserialization.IODataDeserializerProvider DeserializerProvider { public get; } + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task`1[[System.Object]] ReadAsync (Microsoft.OData.ODataMessageReader messageReader, System.Type type, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) +} + +public class Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataCollectionDeserializer : Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataEdmTypeDeserializer, IODataDeserializer, IODataEdmTypeDeserializer { + public ODataCollectionDeserializer (Microsoft.AspNetCore.OData.Formatter.Deserialization.IODataDeserializerProvider deserializerProvider) + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task`1[[System.Object]] ReadAsync (Microsoft.OData.ODataMessageReader messageReader, System.Type type, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) + + public virtual System.Collections.IEnumerable ReadCollectionValue (Microsoft.OData.ODataCollectionValue collectionValue, Microsoft.OData.Edm.IEdmTypeReference elementType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) + public virtual object ReadInline (object item, Microsoft.OData.Edm.IEdmTypeReference edmType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) +} + +public class Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeltaResourceSetDeserializer : Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataEdmTypeDeserializer, IODataDeserializer, IODataEdmTypeDeserializer { + public ODataDeltaResourceSetDeserializer (Microsoft.AspNetCore.OData.Formatter.Deserialization.IODataDeserializerProvider deserializerProvider) + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task`1[[System.Object]] ReadAsync (Microsoft.OData.ODataMessageReader messageReader, System.Type type, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) + + internal virtual object ReadDeltaDeletedLink (Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataDeltaDeletedLinkWrapper deletedLink, Microsoft.OData.Edm.IEdmStructuredTypeReference elementType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) + internal virtual object ReadDeltaLink (Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataDeltaLinkWrapper link, Microsoft.OData.Edm.IEdmStructuredTypeReference elementType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) + public virtual object ReadDeltaResource (Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataResourceWrapper resource, Microsoft.OData.Edm.IEdmStructuredTypeReference elementType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) + public virtual System.Collections.IEnumerable ReadDeltaResourceSet (Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataDeltaResourceSetWrapper deltaResourceSet, Microsoft.OData.Edm.IEdmStructuredTypeReference elementType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) + public virtual object ReadInline (object item, Microsoft.OData.Edm.IEdmTypeReference edmType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) +} + +public class Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext { + public ODataDeserializerContext () + + Microsoft.OData.Edm.IEdmModel Model { public get; public set; } + Microsoft.OData.UriParser.ODataPath Path { public get; public set; } + Microsoft.AspNetCore.Http.HttpRequest Request { public get; public set; } + Microsoft.OData.Edm.IEdmTypeReference ResourceEdmType { public get; public set; } + System.Type ResourceType { public get; public set; } + System.TimeZoneInfo TimeZone { public get; public set; } +} + +public class Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerProvider : IODataDeserializerProvider { + public ODataDeserializerProvider (System.IServiceProvider serviceProvider) + + public virtual Microsoft.AspNetCore.OData.Formatter.Deserialization.IODataEdmTypeDeserializer GetEdmTypeDeserializer (Microsoft.OData.Edm.IEdmTypeReference edmType, params bool isDelta) + public virtual Microsoft.AspNetCore.OData.Formatter.Deserialization.IODataDeserializer GetODataDeserializer (System.Type type, Microsoft.AspNetCore.Http.HttpRequest request) +} + +public class Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataEntityReferenceLinkDeserializer : Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializer, IODataDeserializer { + public ODataEntityReferenceLinkDeserializer () + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task`1[[System.Object]] ReadAsync (Microsoft.OData.ODataMessageReader messageReader, System.Type type, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) +} + +public class Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataEnumDeserializer : Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataEdmTypeDeserializer, IODataDeserializer, IODataEdmTypeDeserializer { + public ODataEnumDeserializer () + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task`1[[System.Object]] ReadAsync (Microsoft.OData.ODataMessageReader messageReader, System.Type type, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) + + public virtual object ReadInline (object item, Microsoft.OData.Edm.IEdmTypeReference edmType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) +} + +public class Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataPrimitiveDeserializer : Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataEdmTypeDeserializer, IODataDeserializer, IODataEdmTypeDeserializer { + public ODataPrimitiveDeserializer () + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task`1[[System.Object]] ReadAsync (Microsoft.OData.ODataMessageReader messageReader, System.Type type, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) + + public virtual object ReadInline (object item, Microsoft.OData.Edm.IEdmTypeReference edmType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) + public virtual object ReadPrimitive (Microsoft.OData.ODataProperty primitiveProperty, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) +} + +public class Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataResourceDeserializer : Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataEdmTypeDeserializer, IODataDeserializer, IODataEdmTypeDeserializer { + public ODataResourceDeserializer (Microsoft.AspNetCore.OData.Formatter.Deserialization.IODataDeserializerProvider deserializerProvider) + + public virtual void ApplyDeletedResource (object resource, Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataResourceWrapper resourceWrapper, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) + public virtual void ApplyNestedProperties (object resource, Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataResourceWrapper resourceWrapper, Microsoft.OData.Edm.IEdmStructuredTypeReference structuredType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) + public virtual void ApplyNestedProperty (object resource, Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataNestedResourceInfoWrapper resourceInfoWrapper, Microsoft.OData.Edm.IEdmStructuredTypeReference structuredType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) + public virtual void ApplyStructuralProperties (object resource, Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataResourceWrapper resourceWrapper, Microsoft.OData.Edm.IEdmStructuredTypeReference structuredType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) + public virtual void ApplyStructuralProperty (object resource, Microsoft.OData.ODataProperty structuralProperty, Microsoft.OData.Edm.IEdmStructuredTypeReference structuredType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) + public virtual object CreateResourceInstance (Microsoft.OData.Edm.IEdmStructuredTypeReference structuredType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task`1[[System.Object]] ReadAsync (Microsoft.OData.ODataMessageReader messageReader, System.Type type, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) + + public virtual object ReadInline (object item, Microsoft.OData.Edm.IEdmTypeReference edmType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) + public virtual object ReadResource (Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataResourceWrapper resourceWrapper, Microsoft.OData.Edm.IEdmStructuredTypeReference structuredType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) +} + +public class Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataResourceSetDeserializer : Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataEdmTypeDeserializer, IODataDeserializer, IODataEdmTypeDeserializer { + public ODataResourceSetDeserializer (Microsoft.AspNetCore.OData.Formatter.Deserialization.IODataDeserializerProvider deserializerProvider) + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task`1[[System.Object]] ReadAsync (Microsoft.OData.ODataMessageReader messageReader, System.Type type, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) + + public virtual object ReadInline (object item, Microsoft.OData.Edm.IEdmTypeReference edmType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) + public virtual System.Collections.IEnumerable ReadResourceSet (Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataResourceSetWrapper resourceSet, Microsoft.OData.Edm.IEdmStructuredTypeReference elementType, Microsoft.AspNetCore.OData.Formatter.Deserialization.ODataDeserializerContext readContext) +} + +public abstract class Microsoft.AspNetCore.OData.Formatter.MediaType.MediaTypeMapping { + protected MediaTypeMapping (string mediaType) + + System.Net.Http.Headers.MediaTypeHeaderValue MediaType { public get; protected set; } + + public abstract double TryMatchMediaType (Microsoft.AspNetCore.Http.HttpRequest request) +} + +public abstract class Microsoft.AspNetCore.OData.Formatter.MediaType.ODataRawValueMediaTypeMapping : Microsoft.AspNetCore.OData.Formatter.MediaType.MediaTypeMapping { + protected ODataRawValueMediaTypeMapping (string mediaType) + + protected abstract bool IsMatch (Microsoft.OData.UriParser.PropertySegment propertySegment) + public virtual double TryMatchMediaType (Microsoft.AspNetCore.Http.HttpRequest request) +} + +public class Microsoft.AspNetCore.OData.Formatter.MediaType.ODataBinaryValueMediaTypeMapping : Microsoft.AspNetCore.OData.Formatter.MediaType.ODataRawValueMediaTypeMapping { + public ODataBinaryValueMediaTypeMapping () + + protected virtual bool IsMatch (Microsoft.OData.UriParser.PropertySegment propertySegment) +} + +public class Microsoft.AspNetCore.OData.Formatter.MediaType.ODataCountMediaTypeMapping : Microsoft.AspNetCore.OData.Formatter.MediaType.MediaTypeMapping { + public ODataCountMediaTypeMapping () + + public virtual double TryMatchMediaType (Microsoft.AspNetCore.Http.HttpRequest request) +} + +public class Microsoft.AspNetCore.OData.Formatter.MediaType.ODataEnumValueMediaTypeMapping : Microsoft.AspNetCore.OData.Formatter.MediaType.ODataRawValueMediaTypeMapping { + public ODataEnumValueMediaTypeMapping () + + protected virtual bool IsMatch (Microsoft.OData.UriParser.PropertySegment propertySegment) +} + +public class Microsoft.AspNetCore.OData.Formatter.MediaType.ODataPrimitiveValueMediaTypeMapping : Microsoft.AspNetCore.OData.Formatter.MediaType.ODataRawValueMediaTypeMapping { + public ODataPrimitiveValueMediaTypeMapping () + + protected virtual bool IsMatch (Microsoft.OData.UriParser.PropertySegment propertySegment) +} + +public class Microsoft.AspNetCore.OData.Formatter.MediaType.ODataStreamMediaTypeMapping : Microsoft.AspNetCore.OData.Formatter.MediaType.MediaTypeMapping { + public ODataStreamMediaTypeMapping () + + public virtual double TryMatchMediaType (Microsoft.AspNetCore.Http.HttpRequest request) +} + +public class Microsoft.AspNetCore.OData.Formatter.MediaType.QueryStringMediaTypeMapping : Microsoft.AspNetCore.OData.Formatter.MediaType.MediaTypeMapping { + public QueryStringMediaTypeMapping (string queryStringParameterName, string mediaType) + public QueryStringMediaTypeMapping (string queryStringParameterName, string queryStringParameterValue, string mediaType) + + string QueryStringParameterName { public get; } + string QueryStringParameterValue { public get; } + + public virtual double TryMatchMediaType (Microsoft.AspNetCore.Http.HttpRequest request) +} + +public interface Microsoft.AspNetCore.OData.Formatter.Serialization.IODataEdmTypeSerializer : IODataSerializer { + Microsoft.OData.ODataValue CreateODataValue (object graph, Microsoft.OData.Edm.IEdmTypeReference expectedType, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) + System.Threading.Tasks.Task WriteObjectInlineAsync (object graph, Microsoft.OData.Edm.IEdmTypeReference expectedType, Microsoft.OData.ODataWriter writer, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) +} + +public interface Microsoft.AspNetCore.OData.Formatter.Serialization.IODataSerializer { + Microsoft.OData.ODataPayloadKind ODataPayloadKind { public abstract get; } + + System.Threading.Tasks.Task WriteObjectAsync (object graph, System.Type type, Microsoft.OData.ODataMessageWriter messageWriter, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) +} + +public interface Microsoft.AspNetCore.OData.Formatter.Serialization.IODataSerializerProvider { + Microsoft.AspNetCore.OData.Formatter.Serialization.IODataEdmTypeSerializer GetEdmTypeSerializer (Microsoft.OData.Edm.IEdmTypeReference edmType) + Microsoft.AspNetCore.OData.Formatter.Serialization.IODataSerializer GetODataPayloadSerializer (System.Type type, Microsoft.AspNetCore.Http.HttpRequest request) +} + +public abstract class Microsoft.AspNetCore.OData.Formatter.Serialization.ODataEdmTypeSerializer : Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializer, IODataEdmTypeSerializer, IODataSerializer { + protected ODataEdmTypeSerializer (Microsoft.OData.ODataPayloadKind payloadKind) + protected ODataEdmTypeSerializer (Microsoft.OData.ODataPayloadKind payloadKind, Microsoft.AspNetCore.OData.Formatter.Serialization.IODataSerializerProvider serializerProvider) + + Microsoft.AspNetCore.OData.Formatter.Serialization.IODataSerializerProvider SerializerProvider { public get; } + + public virtual Microsoft.OData.ODataValue CreateODataValue (object graph, Microsoft.OData.Edm.IEdmTypeReference expectedType, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) + public virtual System.Threading.Tasks.Task WriteObjectInlineAsync (object graph, Microsoft.OData.Edm.IEdmTypeReference expectedType, Microsoft.OData.ODataWriter writer, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) +} + +public abstract class Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializer : IODataSerializer { + protected ODataSerializer (Microsoft.OData.ODataPayloadKind payloadKind) + + Microsoft.OData.ODataPayloadKind ODataPayloadKind { public virtual get; } + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task WriteObjectAsync (object graph, System.Type type, Microsoft.OData.ODataMessageWriter messageWriter, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) +} + +public class Microsoft.AspNetCore.OData.Formatter.Serialization.ODataCollectionSerializer : Microsoft.AspNetCore.OData.Formatter.Serialization.ODataEdmTypeSerializer, IODataEdmTypeSerializer, IODataSerializer { + public ODataCollectionSerializer (Microsoft.AspNetCore.OData.Formatter.Serialization.IODataSerializerProvider serializerProvider) + + protected static void AddTypeNameAnnotationAsNeeded (Microsoft.OData.ODataCollectionValue value, Microsoft.AspNetCore.OData.Formatter.ODataMetadataLevel metadataLevel) + public virtual Microsoft.OData.ODataCollectionValue CreateODataCollectionValue (System.Collections.IEnumerable enumerable, Microsoft.OData.Edm.IEdmTypeReference elementType, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) + public virtual Microsoft.OData.ODataValue CreateODataValue (object graph, Microsoft.OData.Edm.IEdmTypeReference expectedType, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task WriteCollectionAsync (Microsoft.OData.ODataCollectionWriter writer, object graph, Microsoft.OData.Edm.IEdmTypeReference collectionType, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task WriteObjectAsync (object graph, System.Type type, Microsoft.OData.ODataMessageWriter messageWriter, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) +} + +public class Microsoft.AspNetCore.OData.Formatter.Serialization.ODataDeltaResourceSetSerializer : Microsoft.AspNetCore.OData.Formatter.Serialization.ODataEdmTypeSerializer, IODataEdmTypeSerializer, IODataSerializer { + public ODataDeltaResourceSetSerializer (Microsoft.AspNetCore.OData.Formatter.Serialization.IODataSerializerProvider serializerProvider) + + public virtual Microsoft.OData.ODataDeltaResourceSet CreateODataDeltaResourceSet (System.Collections.IEnumerable feedInstance, Microsoft.OData.Edm.IEdmCollectionTypeReference feedType, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task WriteDeltaDeletedLinkAsync (object value, Microsoft.OData.ODataWriter writer, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task WriteDeltaDeletedResourceAsync (object value, Microsoft.OData.ODataWriter writer, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task WriteDeltaLinkAsync (object value, Microsoft.OData.ODataWriter writer, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task WriteObjectAsync (object graph, System.Type type, Microsoft.OData.ODataMessageWriter messageWriter, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task WriteObjectInlineAsync (object graph, Microsoft.OData.Edm.IEdmTypeReference expectedType, Microsoft.OData.ODataWriter writer, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) +} + +public class Microsoft.AspNetCore.OData.Formatter.Serialization.ODataEntityReferenceLinkSerializer : Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializer, IODataSerializer { + public ODataEntityReferenceLinkSerializer () + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task WriteObjectAsync (object graph, System.Type type, Microsoft.OData.ODataMessageWriter messageWriter, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) +} + +public class Microsoft.AspNetCore.OData.Formatter.Serialization.ODataEntityReferenceLinksSerializer : Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializer, IODataSerializer { + public ODataEntityReferenceLinksSerializer () + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task WriteObjectAsync (object graph, System.Type type, Microsoft.OData.ODataMessageWriter messageWriter, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) +} + +public class Microsoft.AspNetCore.OData.Formatter.Serialization.ODataEnumSerializer : Microsoft.AspNetCore.OData.Formatter.Serialization.ODataEdmTypeSerializer, IODataEdmTypeSerializer, IODataSerializer { + public ODataEnumSerializer (Microsoft.AspNetCore.OData.Formatter.Serialization.IODataSerializerProvider serializerProvider) + + public virtual Microsoft.OData.ODataEnumValue CreateODataEnumValue (object graph, Microsoft.OData.Edm.IEdmEnumTypeReference enumType, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) + public virtual Microsoft.OData.ODataValue CreateODataValue (object graph, Microsoft.OData.Edm.IEdmTypeReference expectedType, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task WriteObjectAsync (object graph, System.Type type, Microsoft.OData.ODataMessageWriter messageWriter, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) +} + +public class Microsoft.AspNetCore.OData.Formatter.Serialization.ODataErrorSerializer : Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializer, IODataSerializer { + public ODataErrorSerializer () + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task WriteObjectAsync (object graph, System.Type type, Microsoft.OData.ODataMessageWriter messageWriter, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) +} + +public class Microsoft.AspNetCore.OData.Formatter.Serialization.ODataMetadataSerializer : Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializer, IODataSerializer { + public ODataMetadataSerializer () + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task WriteObjectAsync (object graph, System.Type type, Microsoft.OData.ODataMessageWriter messageWriter, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) +} + +public class Microsoft.AspNetCore.OData.Formatter.Serialization.ODataPrimitiveSerializer : Microsoft.AspNetCore.OData.Formatter.Serialization.ODataEdmTypeSerializer, IODataEdmTypeSerializer, IODataSerializer { + public ODataPrimitiveSerializer () + + public virtual Microsoft.OData.ODataPrimitiveValue CreateODataPrimitiveValue (object graph, Microsoft.OData.Edm.IEdmPrimitiveTypeReference primitiveType, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) + public virtual Microsoft.OData.ODataValue CreateODataValue (object graph, Microsoft.OData.Edm.IEdmTypeReference expectedType, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task WriteObjectAsync (object graph, System.Type type, Microsoft.OData.ODataMessageWriter messageWriter, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) +} + +public class Microsoft.AspNetCore.OData.Formatter.Serialization.ODataRawValueSerializer : Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializer, IODataSerializer { + public ODataRawValueSerializer () + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task WriteObjectAsync (object graph, System.Type type, Microsoft.OData.ODataMessageWriter messageWriter, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) +} + +public class Microsoft.AspNetCore.OData.Formatter.Serialization.ODataResourceSerializer : Microsoft.AspNetCore.OData.Formatter.Serialization.ODataEdmTypeSerializer, IODataEdmTypeSerializer, IODataSerializer { + public ODataResourceSerializer (Microsoft.AspNetCore.OData.Formatter.Serialization.IODataSerializerProvider serializerProvider) + + public virtual void AppendDynamicProperties (Microsoft.OData.ODataResource resource, Microsoft.AspNetCore.OData.Formatter.Serialization.SelectExpandNode selectExpandNode, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) + public virtual Microsoft.OData.ODataProperty CreateComputedProperty (string propertyName, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) + public virtual string CreateETag (Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) + public virtual Microsoft.OData.ODataNestedResourceInfo CreateNavigationLink (Microsoft.OData.Edm.IEdmNavigationProperty navigationProperty, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) + public virtual Microsoft.OData.ODataAction CreateODataAction (Microsoft.OData.Edm.IEdmAction action, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) + public virtual Microsoft.OData.ODataFunction CreateODataFunction (Microsoft.OData.Edm.IEdmFunction function, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) + public virtual Microsoft.OData.ODataResource CreateResource (Microsoft.AspNetCore.OData.Formatter.Serialization.SelectExpandNode selectExpandNode, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) + public virtual Microsoft.AspNetCore.OData.Formatter.Serialization.SelectExpandNode CreateSelectExpandNode (Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) + public virtual Microsoft.OData.ODataStreamPropertyInfo CreateStreamProperty (Microsoft.OData.Edm.IEdmStructuralProperty structuralProperty, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) + public virtual Microsoft.OData.ODataProperty CreateStructuralProperty (Microsoft.OData.Edm.IEdmStructuralProperty structuralProperty, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task WriteDeltaObjectInlineAsync (object graph, Microsoft.OData.Edm.IEdmTypeReference expectedType, Microsoft.OData.ODataWriter writer, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task WriteObjectAsync (object graph, System.Type type, Microsoft.OData.ODataMessageWriter messageWriter, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task WriteObjectInlineAsync (object graph, Microsoft.OData.Edm.IEdmTypeReference expectedType, Microsoft.OData.ODataWriter writer, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) +} + +public class Microsoft.AspNetCore.OData.Formatter.Serialization.ODataResourceSetSerializer : Microsoft.AspNetCore.OData.Formatter.Serialization.ODataEdmTypeSerializer, IODataEdmTypeSerializer, IODataSerializer { + public ODataResourceSetSerializer (Microsoft.AspNetCore.OData.Formatter.Serialization.IODataSerializerProvider serializerProvider) + + public virtual Microsoft.OData.ODataOperation CreateODataOperation (Microsoft.OData.Edm.IEdmOperation operation, Microsoft.AspNetCore.OData.Formatter.ResourceSetContext resourceSetContext, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) + public virtual Microsoft.OData.ODataResourceSet CreateResourceSet (System.Collections.IEnumerable resourceSetInstance, Microsoft.OData.Edm.IEdmCollectionTypeReference resourceSetType, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task WriteObjectAsync (object graph, System.Type type, Microsoft.OData.ODataMessageWriter messageWriter, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task WriteObjectInlineAsync (object graph, Microsoft.OData.Edm.IEdmTypeReference expectedType, Microsoft.OData.ODataWriter writer, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) +} + +public class Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext { + public ODataSerializerContext () + public ODataSerializerContext (Microsoft.AspNetCore.OData.Formatter.ResourceContext resource, Microsoft.OData.UriParser.SelectExpandClause selectExpandClause, Microsoft.OData.Edm.IEdmProperty edmProperty) + + System.Collections.Generic.ISet`1[[System.String]] ComputedProperties { public get; } + Microsoft.OData.Edm.IEdmProperty EdmProperty { public get; public set; } + Microsoft.AspNetCore.OData.Formatter.ResourceContext ExpandedResource { public get; public set; } + bool ExpandReference { public get; public set; } + System.Collections.Generic.IDictionary`2[[System.Object],[System.Object]] Items { public get; } + Microsoft.AspNetCore.OData.Formatter.ODataMetadataLevel MetadataLevel { public get; public set; } + Microsoft.OData.Edm.IEdmModel Model { public get; public set; } + Microsoft.OData.Edm.IEdmNavigationProperty NavigationProperty { public get; } + Microsoft.OData.Edm.IEdmNavigationSource NavigationSource { public get; public set; } + Microsoft.OData.UriParser.ODataPath Path { public get; public set; } + Microsoft.AspNetCore.OData.Query.ODataQueryOptions QueryOptions { public get; } + Microsoft.AspNetCore.Http.HttpRequest Request { public get; public set; } + string RootElementName { public get; public set; } + Microsoft.OData.UriParser.SelectExpandClause SelectExpandClause { public get; public set; } + bool SkipExpensiveAvailabilityChecks { public get; public set; } + System.TimeZoneInfo TimeZone { public get; public set; } +} + +public class Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerProvider : IODataSerializerProvider { + public ODataSerializerProvider (System.IServiceProvider serviceProvider) + + public virtual Microsoft.AspNetCore.OData.Formatter.Serialization.IODataEdmTypeSerializer GetEdmTypeSerializer (Microsoft.OData.Edm.IEdmTypeReference edmType) + public virtual Microsoft.AspNetCore.OData.Formatter.Serialization.IODataSerializer GetODataPayloadSerializer (System.Type type, Microsoft.AspNetCore.Http.HttpRequest request) +} + +public class Microsoft.AspNetCore.OData.Formatter.Serialization.ODataServiceDocumentSerializer : Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializer, IODataSerializer { + public ODataServiceDocumentSerializer () + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task WriteObjectAsync (object graph, System.Type type, Microsoft.OData.ODataMessageWriter messageWriter, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) +} + +public class Microsoft.AspNetCore.OData.Formatter.Serialization.SelectExpandNode { + public SelectExpandNode () + public SelectExpandNode (Microsoft.OData.Edm.IEdmStructuredType structuredType, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) + public SelectExpandNode (Microsoft.OData.UriParser.SelectExpandClause selectExpandClause, Microsoft.OData.Edm.IEdmStructuredType structuredType, Microsoft.OData.Edm.IEdmModel model) + + System.Collections.Generic.IDictionary`2[[Microsoft.OData.Edm.IEdmNavigationProperty],[Microsoft.OData.UriParser.ExpandedNavigationSelectItem]] ExpandedProperties { public get; } + System.Collections.Generic.IDictionary`2[[Microsoft.OData.Edm.IEdmNavigationProperty],[Microsoft.OData.UriParser.ExpandedReferenceSelectItem]] ReferencedProperties { public get; } + bool SelectAllDynamicProperties { public get; } + System.Collections.Generic.ISet`1[[Microsoft.OData.Edm.IEdmAction]] SelectedActions { public get; } + System.Collections.Generic.IDictionary`2[[Microsoft.OData.Edm.IEdmStructuralProperty],[Microsoft.OData.UriParser.PathSelectItem]] SelectedComplexProperties { public get; } + System.Collections.Generic.ISet`1[[System.String]] SelectedComputedProperties { public get; } + System.Collections.Generic.ISet`1[[System.String]] SelectedDynamicProperties { public get; } + System.Collections.Generic.ISet`1[[Microsoft.OData.Edm.IEdmFunction]] SelectedFunctions { public get; } + System.Collections.Generic.ISet`1[[Microsoft.OData.Edm.IEdmNavigationProperty]] SelectedNavigationProperties { public get; } + System.Collections.Generic.ISet`1[[Microsoft.OData.Edm.IEdmStructuralProperty]] SelectedStructuralProperties { public get; } +} + +public interface Microsoft.AspNetCore.OData.Formatter.Value.IEdmChangedObject : IEdmObject { + Microsoft.AspNetCore.OData.Deltas.DeltaItemKind Kind { public abstract get; } +} + +public interface Microsoft.AspNetCore.OData.Formatter.Value.IEdmComplexObject : IEdmObject, IEdmStructuredObject { +} + +public interface Microsoft.AspNetCore.OData.Formatter.Value.IEdmDeltaDeletedLink : IEdmChangedObject, IEdmDeltaLinkBase, IEdmObject { +} + +public interface Microsoft.AspNetCore.OData.Formatter.Value.IEdmDeltaDeletedResourceObject : IEdmChangedObject, IEdmObject { + System.Uri Id { public abstract get; public abstract set; } + System.Nullable`1[[Microsoft.OData.DeltaDeletedEntryReason]] Reason { public abstract get; public abstract set; } +} + +public interface Microsoft.AspNetCore.OData.Formatter.Value.IEdmDeltaLink : IEdmChangedObject, IEdmDeltaLinkBase, IEdmObject { +} + +public interface Microsoft.AspNetCore.OData.Formatter.Value.IEdmDeltaLinkBase : IEdmChangedObject, IEdmObject { + string Relationship { public abstract get; public abstract set; } + System.Uri Source { public abstract get; public abstract set; } + System.Uri Target { public abstract get; public abstract set; } +} + +public interface Microsoft.AspNetCore.OData.Formatter.Value.IEdmEntityObject : IEdmObject, IEdmStructuredObject { +} + +public interface Microsoft.AspNetCore.OData.Formatter.Value.IEdmEnumObject : IEdmObject { +} + +public interface Microsoft.AspNetCore.OData.Formatter.Value.IEdmObject { + Microsoft.OData.Edm.IEdmTypeReference GetEdmType () +} + +public interface Microsoft.AspNetCore.OData.Formatter.Value.IEdmStructuredObject : IEdmObject { + bool TryGetPropertyValue (string propertyName, out System.Object& value) +} + +public abstract class Microsoft.AspNetCore.OData.Formatter.Value.EdmDeltaLinkBase : IEdmChangedObject, IEdmDeltaLinkBase, IEdmObject { + protected EdmDeltaLinkBase (Microsoft.OData.Edm.IEdmEntityTypeReference typeReference) + protected EdmDeltaLinkBase (Microsoft.OData.Edm.IEdmEntityType entityType, bool isNullable) + + Microsoft.OData.Edm.IEdmEntityType EntityType { public get; } + bool IsNullable { public get; } + Microsoft.AspNetCore.OData.Deltas.DeltaItemKind Kind { public abstract get; } + string Relationship { public virtual get; public virtual set; } + System.Uri Source { public virtual get; public virtual set; } + System.Uri Target { public virtual get; public virtual set; } + + public virtual Microsoft.OData.Edm.IEdmTypeReference GetEdmType () +} + +[ +NonValidatingParameterBindingAttribute(), +] +public abstract class Microsoft.AspNetCore.OData.Formatter.Value.EdmStructuredObject : Microsoft.AspNetCore.OData.Deltas.Delta, IDynamicMetaObjectProvider, IDelta, IDeltaSetItem, IEdmChangedObject, IEdmObject, IEdmStructuredObject { + protected EdmStructuredObject (Microsoft.OData.Edm.IEdmStructuredType edmType) + protected EdmStructuredObject (Microsoft.OData.Edm.IEdmStructuredTypeReference edmType) + protected EdmStructuredObject (Microsoft.OData.Edm.IEdmStructuredType edmType, bool isNullable) + + Microsoft.OData.Edm.IEdmStructuredType ActualEdmType { public get; public set; } + Microsoft.OData.Edm.IEdmStructuredType ExpectedEdmType { public get; public set; } + bool IsNullable { public get; public set; } + Microsoft.AspNetCore.OData.Deltas.DeltaItemKind Kind { public virtual get; } + + public virtual void Clear () + public virtual System.Collections.Generic.IEnumerable`1[[System.String]] GetChangedPropertyNames () + public virtual Microsoft.OData.Edm.IEdmTypeReference GetEdmType () + public virtual System.Collections.Generic.IEnumerable`1[[System.String]] GetUnchangedPropertyNames () + public System.Collections.Generic.Dictionary`2[[System.String],[System.Object]] TryGetDynamicProperties () + public virtual bool TryGetPropertyType (string name, out System.Type& type) + public virtual bool TryGetPropertyValue (string name, out System.Object& value) + public virtual bool TrySetPropertyValue (string name, object value) +} + +[ +ExtensionAttribute(), +] +public sealed class Microsoft.AspNetCore.OData.Formatter.Value.EdmTypeExtensions { + [ + ExtensionAttribute(), + ] + public static bool IsDeltaResource (Microsoft.AspNetCore.OData.Formatter.Value.IEdmObject resource) + + [ + ExtensionAttribute(), + ] + public static bool IsDeltaResourceSet (Microsoft.OData.Edm.IEdmType type) +} + +[ +NonValidatingParameterBindingAttribute(), +] +public class Microsoft.AspNetCore.OData.Formatter.Value.EdmChangedObjectCollection : System.Collections.ObjectModel.Collection`1[[Microsoft.AspNetCore.OData.Formatter.Value.IEdmChangedObject]], ICollection, IEnumerable, IList, IEdmObject, ICollection`1, IEnumerable`1, IList`1, IReadOnlyCollection`1, IReadOnlyList`1 { + public EdmChangedObjectCollection (Microsoft.OData.Edm.IEdmEntityType entityType) + public EdmChangedObjectCollection (Microsoft.OData.Edm.IEdmEntityType entityType, System.Collections.Generic.IList`1[[Microsoft.AspNetCore.OData.Formatter.Value.IEdmChangedObject]] changedObjectList) + + public virtual Microsoft.OData.Edm.IEdmTypeReference GetEdmType () +} + +[ +NonValidatingParameterBindingAttribute(), +] +public class Microsoft.AspNetCore.OData.Formatter.Value.EdmComplexObject : Microsoft.AspNetCore.OData.Formatter.Value.EdmStructuredObject, IDynamicMetaObjectProvider, IDelta, IDeltaSetItem, IEdmChangedObject, IEdmComplexObject, IEdmObject, IEdmStructuredObject { + public EdmComplexObject (Microsoft.OData.Edm.IEdmComplexType edmType) + public EdmComplexObject (Microsoft.OData.Edm.IEdmComplexTypeReference edmType) + public EdmComplexObject (Microsoft.OData.Edm.IEdmComplexType edmType, bool isNullable) +} + +[ +NonValidatingParameterBindingAttribute(), +] +public class Microsoft.AspNetCore.OData.Formatter.Value.EdmComplexObjectCollection : System.Collections.ObjectModel.Collection`1[[Microsoft.AspNetCore.OData.Formatter.Value.IEdmComplexObject]], ICollection, IEnumerable, IList, IEdmObject, ICollection`1, IEnumerable`1, IList`1, IReadOnlyCollection`1, IReadOnlyList`1 { + public EdmComplexObjectCollection (Microsoft.OData.Edm.IEdmCollectionTypeReference edmType) + public EdmComplexObjectCollection (Microsoft.OData.Edm.IEdmCollectionTypeReference edmType, System.Collections.Generic.IList`1[[Microsoft.AspNetCore.OData.Formatter.Value.IEdmComplexObject]] list) + + public virtual Microsoft.OData.Edm.IEdmTypeReference GetEdmType () +} + +[ +NonValidatingParameterBindingAttribute(), +] +public class Microsoft.AspNetCore.OData.Formatter.Value.EdmDeltaComplexObject : Microsoft.AspNetCore.OData.Formatter.Value.EdmComplexObject, IDynamicMetaObjectProvider, IDelta, IDeltaSetItem, IEdmChangedObject, IEdmComplexObject, IEdmObject, IEdmStructuredObject { + public EdmDeltaComplexObject (Microsoft.OData.Edm.IEdmComplexType edmType) + public EdmDeltaComplexObject (Microsoft.OData.Edm.IEdmComplexTypeReference edmType) + public EdmDeltaComplexObject (Microsoft.OData.Edm.IEdmComplexType edmType, bool isNullable) +} + +[ +NonValidatingParameterBindingAttribute(), +] +public class Microsoft.AspNetCore.OData.Formatter.Value.EdmDeltaDeletedLink : Microsoft.AspNetCore.OData.Formatter.Value.EdmDeltaLinkBase, IEdmChangedObject, IEdmDeltaDeletedLink, IEdmDeltaLinkBase, IEdmObject { + public EdmDeltaDeletedLink (Microsoft.OData.Edm.IEdmEntityType entityType) + public EdmDeltaDeletedLink (Microsoft.OData.Edm.IEdmEntityTypeReference entityTypeReference) + public EdmDeltaDeletedLink (Microsoft.OData.Edm.IEdmEntityType entityType, bool isNullable) + + Microsoft.AspNetCore.OData.Deltas.DeltaItemKind Kind { public virtual get; } +} + +[ +NonValidatingParameterBindingAttribute(), +] +public class Microsoft.AspNetCore.OData.Formatter.Value.EdmDeltaDeletedResourceObject : Microsoft.AspNetCore.OData.Formatter.Value.EdmEntityObject, IDynamicMetaObjectProvider, IDelta, IDeltaSetItem, IEdmChangedObject, IEdmDeltaDeletedResourceObject, IEdmEntityObject, IEdmObject, IEdmStructuredObject { + public EdmDeltaDeletedResourceObject (Microsoft.OData.Edm.IEdmEntityType entityType) + public EdmDeltaDeletedResourceObject (Microsoft.OData.Edm.IEdmEntityTypeReference entityTypeReference) + public EdmDeltaDeletedResourceObject (Microsoft.OData.Edm.IEdmEntityType entityType, bool isNullable) + + System.Uri Id { public virtual get; public virtual set; } + Microsoft.AspNetCore.OData.Deltas.DeltaItemKind Kind { public virtual get; } + Microsoft.OData.Edm.IEdmNavigationSource NavigationSource { public get; public set; } + System.Nullable`1[[Microsoft.OData.DeltaDeletedEntryReason]] Reason { public virtual get; public virtual set; } +} + +[ +NonValidatingParameterBindingAttribute(), +] +public class Microsoft.AspNetCore.OData.Formatter.Value.EdmDeltaLink : Microsoft.AspNetCore.OData.Formatter.Value.EdmDeltaLinkBase, IEdmChangedObject, IEdmDeltaLink, IEdmDeltaLinkBase, IEdmObject { + public EdmDeltaLink (Microsoft.OData.Edm.IEdmEntityType entityType) + public EdmDeltaLink (Microsoft.OData.Edm.IEdmEntityTypeReference entityTypeReference) + public EdmDeltaLink (Microsoft.OData.Edm.IEdmEntityType entityType, bool isNullable) + + Microsoft.AspNetCore.OData.Deltas.DeltaItemKind Kind { public virtual get; } +} + +[ +NonValidatingParameterBindingAttribute(), +] +public class Microsoft.AspNetCore.OData.Formatter.Value.EdmDeltaResourceObject : Microsoft.AspNetCore.OData.Formatter.Value.EdmEntityObject, IDynamicMetaObjectProvider, IDelta, IDeltaSetItem, IEdmChangedObject, IEdmEntityObject, IEdmObject, IEdmStructuredObject { + public EdmDeltaResourceObject (Microsoft.OData.Edm.IEdmEntityType entityType) + public EdmDeltaResourceObject (Microsoft.OData.Edm.IEdmEntityTypeReference entityTypeReference) + public EdmDeltaResourceObject (Microsoft.OData.Edm.IEdmEntityType entityType, bool isNullable) + + Microsoft.AspNetCore.OData.Deltas.DeltaItemKind DeltaKind { public get; } + Microsoft.OData.Edm.IEdmNavigationSource NavigationSource { public get; public set; } +} + +[ +NonValidatingParameterBindingAttribute(), +] +public class Microsoft.AspNetCore.OData.Formatter.Value.EdmEntityObject : Microsoft.AspNetCore.OData.Formatter.Value.EdmStructuredObject, IDynamicMetaObjectProvider, IDelta, IDeltaSetItem, IEdmChangedObject, IEdmEntityObject, IEdmObject, IEdmStructuredObject { + public EdmEntityObject (Microsoft.OData.Edm.IEdmEntityType edmType) + public EdmEntityObject (Microsoft.OData.Edm.IEdmEntityTypeReference edmType) + public EdmEntityObject (Microsoft.OData.Edm.IEdmEntityType edmType, bool isNullable) +} + +[ +NonValidatingParameterBindingAttribute(), +] +public class Microsoft.AspNetCore.OData.Formatter.Value.EdmEntityObjectCollection : System.Collections.ObjectModel.Collection`1[[Microsoft.AspNetCore.OData.Formatter.Value.IEdmEntityObject]], ICollection, IEnumerable, IList, IEdmObject, ICollection`1, IEnumerable`1, IList`1, IReadOnlyCollection`1, IReadOnlyList`1 { + public EdmEntityObjectCollection (Microsoft.OData.Edm.IEdmCollectionTypeReference edmType) + public EdmEntityObjectCollection (Microsoft.OData.Edm.IEdmCollectionTypeReference edmType, System.Collections.Generic.IList`1[[Microsoft.AspNetCore.OData.Formatter.Value.IEdmEntityObject]] list) + + public virtual Microsoft.OData.Edm.IEdmTypeReference GetEdmType () +} + +[ +NonValidatingParameterBindingAttribute(), +] +public class Microsoft.AspNetCore.OData.Formatter.Value.EdmEnumObject : IEdmEnumObject, IEdmObject { + public EdmEnumObject (Microsoft.OData.Edm.IEdmEnumType edmType, string value) + public EdmEnumObject (Microsoft.OData.Edm.IEdmEnumTypeReference edmType, string value) + public EdmEnumObject (Microsoft.OData.Edm.IEdmEnumType edmType, string value, bool isNullable) + + bool IsNullable { public get; public set; } + string Value { public get; public set; } + + public virtual Microsoft.OData.Edm.IEdmTypeReference GetEdmType () +} + +[ +NonValidatingParameterBindingAttribute(), +] +public class Microsoft.AspNetCore.OData.Formatter.Value.EdmEnumObjectCollection : System.Collections.ObjectModel.Collection`1[[Microsoft.AspNetCore.OData.Formatter.Value.IEdmEnumObject]], ICollection, IEnumerable, IList, IEdmObject, ICollection`1, IEnumerable`1, IList`1, IReadOnlyCollection`1, IReadOnlyList`1 { + public EdmEnumObjectCollection (Microsoft.OData.Edm.IEdmCollectionTypeReference edmType) + public EdmEnumObjectCollection (Microsoft.OData.Edm.IEdmCollectionTypeReference edmType, System.Collections.Generic.IList`1[[Microsoft.AspNetCore.OData.Formatter.Value.IEdmEnumObject]] list) + + public virtual Microsoft.OData.Edm.IEdmTypeReference GetEdmType () +} + +public class Microsoft.AspNetCore.OData.Formatter.Value.NullEdmComplexObject : IEdmComplexObject, IEdmObject, IEdmStructuredObject { + public NullEdmComplexObject (Microsoft.OData.Edm.IEdmComplexTypeReference edmType) + + public virtual Microsoft.OData.Edm.IEdmTypeReference GetEdmType () + public virtual bool TryGetPropertyValue (string propertyName, out System.Object& value) +} + +public abstract class Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataDeltaLinkBaseWrapper : Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataItemWrapper { + protected ODataDeltaLinkBaseWrapper () +} + +public abstract class Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataItemWrapper { + protected ODataItemWrapper () +} + +public abstract class Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataResourceSetBaseWrapper : Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataItemWrapper { + protected ODataResourceSetBaseWrapper () +} + +[ +ExtensionAttribute(), +] +public sealed class Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataReaderExtensions { + [ + ExtensionAttribute(), + ] + public static Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataItemWrapper ReadResourceOrResourceSet (Microsoft.OData.ODataReader reader) + + [ + AsyncStateMachineAttribute(), + ExtensionAttribute(), + ] + public static System.Threading.Tasks.Task`1[[Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataItemWrapper]] ReadResourceOrResourceSetAsync (Microsoft.OData.ODataReader reader) +} + +public class Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataEntityReferenceLinkWrapper : Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataItemWrapper { + public ODataEntityReferenceLinkWrapper (Microsoft.OData.ODataEntityReferenceLink link) + + Microsoft.OData.ODataEntityReferenceLink EntityReferenceLink { public get; } +} + +public sealed class Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataDeltaDeletedLinkWrapper : Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataDeltaLinkBaseWrapper { + public ODataDeltaDeletedLinkWrapper (Microsoft.OData.ODataDeltaDeletedLink deltaDeletedLink) + + Microsoft.OData.ODataDeltaDeletedLink DeltaDeletedLink { public get; } +} + +public sealed class Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataDeltaLinkWrapper : Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataDeltaLinkBaseWrapper { + public ODataDeltaLinkWrapper (Microsoft.OData.ODataDeltaLink deltaLink) + + Microsoft.OData.ODataDeltaLink DeltaLink { public get; } +} + +public sealed class Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataDeltaResourceSetWrapper : Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataResourceSetBaseWrapper { + public ODataDeltaResourceSetWrapper (Microsoft.OData.ODataDeltaResourceSet deltaResourceSet) + + System.Collections.Generic.IList`1[[Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataItemWrapper]] DeltaItems { public get; } + Microsoft.OData.ODataDeltaResourceSet DeltaResourceSet { public get; } +} + +public sealed class Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataNestedResourceInfoWrapper : Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataItemWrapper { + public ODataNestedResourceInfoWrapper (Microsoft.OData.ODataNestedResourceInfo nestedInfo) + + System.Collections.Generic.IList`1[[Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataItemWrapper]] NestedItems { public get; } + Microsoft.OData.ODataNestedResourceInfo NestedResourceInfo { public get; } +} + +public sealed class Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataResourceSetWrapper : Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataResourceSetBaseWrapper { + public ODataResourceSetWrapper (Microsoft.OData.ODataResourceSet resourceSet) + + System.Collections.Generic.IList`1[[Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataResourceWrapper]] Resources { public get; } + Microsoft.OData.ODataResourceSet ResourceSet { public get; } +} + +public sealed class Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataResourceWrapper : Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataItemWrapper { + public ODataResourceWrapper (Microsoft.OData.ODataResourceBase resource) + + bool IsDeletedResource { public get; } + System.Collections.Generic.IList`1[[Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataNestedResourceInfoWrapper]] NestedResourceInfos { public get; } + Microsoft.OData.ODataResourceBase Resource { public get; } +} + +public interface Microsoft.AspNetCore.OData.Query.Container.IPropertyMapper { + string MapProperty (string propertyName) +} + +public interface Microsoft.AspNetCore.OData.Query.Container.ITruncatedCollection : IEnumerable { + bool IsTruncated { public abstract get; } + int PageSize { public abstract get; } +} + +public class Microsoft.AspNetCore.OData.Query.Container.NamedPropertyExpression { + public NamedPropertyExpression (System.Linq.Expressions.Expression name, System.Linq.Expressions.Expression value) + + bool AutoSelected { public get; public set; } + System.Nullable`1[[System.Boolean]] CountOption { public get; public set; } + System.Linq.Expressions.Expression Name { public get; } + System.Linq.Expressions.Expression NullCheck { public get; public set; } + System.Nullable`1[[System.Int32]] PageSize { public get; public set; } + System.Linq.Expressions.Expression TotalCount { public get; public set; } + System.Linq.Expressions.Expression Value { public get; } +} + +public class Microsoft.AspNetCore.OData.Query.Container.TruncatedCollection`1 : List`1, ICollection`1, IEnumerable`1, IList`1, IReadOnlyCollection`1, IReadOnlyList`1, ICollection, IEnumerable, IList, ICountOptionCollection, ITruncatedCollection { + public TruncatedCollection`1 (IEnumerable`1 source, int pageSize) + public TruncatedCollection`1 (IQueryable`1 source, int pageSize) + public TruncatedCollection`1 (IEnumerable`1 source, int pageSize, System.Nullable`1[[System.Int64]] totalCount) + public TruncatedCollection`1 (IQueryable`1 source, int pageSize, bool parameterize) + public TruncatedCollection`1 (IQueryable`1 source, int pageSize, System.Nullable`1[[System.Int64]] totalCount) + public TruncatedCollection`1 (IQueryable`1 source, int pageSize, System.Nullable`1[[System.Int64]] totalCount, bool parameterize) + + bool IsTruncated { public virtual get; } + int PageSize { public virtual get; } + System.Nullable`1[[System.Int64]] TotalCount { public virtual get; } +} + +public interface Microsoft.AspNetCore.OData.Query.Expressions.IFilterBinder { + System.Linq.Expressions.Expression BindFilter (Microsoft.OData.UriParser.FilterClause filterClause, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) +} + +public interface Microsoft.AspNetCore.OData.Query.Expressions.IOrderByBinder { + Microsoft.AspNetCore.OData.Query.Expressions.OrderByBinderResult BindOrderBy (Microsoft.OData.UriParser.OrderByClause orderByClause, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) +} + +public interface Microsoft.AspNetCore.OData.Query.Expressions.ISearchBinder { + System.Linq.Expressions.Expression BindSearch (Microsoft.OData.UriParser.SearchClause searchClause, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) +} + +public interface Microsoft.AspNetCore.OData.Query.Expressions.ISelectExpandBinder { + System.Linq.Expressions.Expression BindSelectExpand (Microsoft.OData.UriParser.SelectExpandClause selectExpandClause, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) +} + +public abstract class Microsoft.AspNetCore.OData.Query.Expressions.ExpressionBinderBase { + protected ExpressionBinderBase (System.IServiceProvider requestContainer) + + System.Linq.Expressions.ParameterExpression Parameter { protected abstract get; } + + public abstract System.Linq.Expressions.Expression Bind (Microsoft.OData.UriParser.QueryNode node) + protected System.Linq.Expressions.Expression[] BindArguments (System.Collections.Generic.IEnumerable`1[[Microsoft.OData.UriParser.QueryNode]] nodes) + public virtual System.Linq.Expressions.Expression BindCollectionConstantNode (Microsoft.OData.UriParser.CollectionConstantNode node) + public virtual System.Linq.Expressions.Expression BindConstantNode (Microsoft.OData.UriParser.ConstantNode constantNode) + public virtual System.Linq.Expressions.Expression BindSingleValueFunctionCallNode (Microsoft.OData.UriParser.SingleValueFunctionCallNode node) + protected void EnsureFlattenedPropertyContainer (System.Linq.Expressions.ParameterExpression source) + protected System.Reflection.PropertyInfo GetDynamicPropertyContainer (Microsoft.OData.UriParser.SingleValueOpenPropertyAccessNode openNode) + protected System.Linq.Expressions.Expression GetFlattenedPropertyExpression (string propertyPath) +} + +public abstract class Microsoft.AspNetCore.OData.Query.Expressions.QueryBinder { + protected QueryBinder () + + protected static System.Linq.Expressions.Expression ApplyNullPropagationForFilterBody (System.Linq.Expressions.Expression body, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + public virtual System.Linq.Expressions.Expression Bind (Microsoft.OData.UriParser.QueryNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + public virtual System.Linq.Expressions.Expression BindAllNode (Microsoft.OData.UriParser.AllNode allNode, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + public virtual System.Linq.Expressions.Expression BindAnyNode (Microsoft.OData.UriParser.AnyNode anyNode, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + protected System.Linq.Expressions.Expression[] BindArguments (System.Collections.Generic.IEnumerable`1[[Microsoft.OData.UriParser.QueryNode]] nodes, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + public virtual System.Linq.Expressions.Expression BindBinaryOperatorNode (Microsoft.OData.UriParser.BinaryOperatorNode binaryOperatorNode, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + protected virtual System.Linq.Expressions.Expression BindCastSingleValue (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + protected virtual System.Linq.Expressions.Expression BindCeiling (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + public virtual System.Linq.Expressions.Expression BindCollectionComplexNode (Microsoft.OData.UriParser.CollectionComplexNode collectionComplexNode, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + public virtual System.Linq.Expressions.Expression BindCollectionConstantNode (Microsoft.OData.UriParser.CollectionConstantNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + public virtual System.Linq.Expressions.Expression BindCollectionNode (Microsoft.OData.UriParser.CollectionNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + public virtual System.Linq.Expressions.Expression BindCollectionPropertyAccessNode (Microsoft.OData.UriParser.CollectionPropertyAccessNode propertyAccessNode, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + public virtual System.Linq.Expressions.Expression BindCollectionResourceCastNode (Microsoft.OData.UriParser.CollectionResourceCastNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + protected virtual System.Linq.Expressions.Expression BindConcat (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + public virtual System.Linq.Expressions.Expression BindConstantNode (Microsoft.OData.UriParser.ConstantNode constantNode, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + protected virtual System.Linq.Expressions.Expression BindContains (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + public virtual System.Linq.Expressions.Expression BindConvertNode (Microsoft.OData.UriParser.ConvertNode convertNode, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + public virtual System.Linq.Expressions.Expression BindCountNode (Microsoft.OData.UriParser.CountNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + protected virtual System.Linq.Expressions.Expression BindCustomMethodExpressionOrNull (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + protected virtual System.Linq.Expressions.Expression BindDate (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + protected virtual System.Linq.Expressions.Expression BindDateRelatedProperty (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + public virtual System.Linq.Expressions.Expression BindDynamicPropertyAccessQueryNode (Microsoft.OData.UriParser.SingleValueOpenPropertyAccessNode openNode, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + protected virtual System.Linq.Expressions.Expression BindEndsWith (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + protected virtual System.Linq.Expressions.Expression BindFloor (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + protected virtual System.Linq.Expressions.Expression BindFractionalSeconds (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + protected virtual System.Linq.Expressions.Expression BindIndexOf (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + public virtual System.Linq.Expressions.Expression BindInNode (Microsoft.OData.UriParser.InNode inNode, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + protected virtual System.Linq.Expressions.Expression BindIsOf (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + protected virtual System.Linq.Expressions.Expression BindLength (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + public virtual System.Linq.Expressions.Expression BindNavigationPropertyNode (Microsoft.OData.UriParser.QueryNode sourceNode, Microsoft.OData.Edm.IEdmNavigationProperty navigationProperty, string propertyPath, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + protected virtual System.Linq.Expressions.Expression BindNow (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + public virtual System.Linq.Expressions.Expression BindPropertyAccessQueryNode (Microsoft.OData.UriParser.SingleValuePropertyAccessNode propertyAccessNode, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + public virtual System.Linq.Expressions.Expression BindRangeVariable (Microsoft.OData.UriParser.RangeVariable rangeVariable, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + protected virtual System.Linq.Expressions.Expression BindRound (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + public virtual System.Linq.Expressions.Expression BindSingleComplexNode (Microsoft.OData.UriParser.SingleComplexNode singleComplexNode, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + public virtual System.Linq.Expressions.Expression BindSingleResourceCastFunctionCall (Microsoft.OData.UriParser.SingleResourceFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + public virtual System.Linq.Expressions.Expression BindSingleResourceCastNode (Microsoft.OData.UriParser.SingleResourceCastNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + public virtual System.Linq.Expressions.Expression BindSingleResourceFunctionCallNode (Microsoft.OData.UriParser.SingleResourceFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + public virtual System.Linq.Expressions.Expression BindSingleValueFunctionCallNode (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + public virtual System.Linq.Expressions.Expression BindSingleValueNode (Microsoft.OData.UriParser.SingleValueNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + protected virtual System.Linq.Expressions.Expression BindStartsWith (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + protected virtual System.Linq.Expressions.Expression BindSubstring (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + protected virtual System.Linq.Expressions.Expression BindTime (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + protected virtual System.Linq.Expressions.Expression BindTimeRelatedProperty (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + protected virtual System.Linq.Expressions.Expression BindToLower (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + protected virtual System.Linq.Expressions.Expression BindToUpper (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + protected virtual System.Linq.Expressions.Expression BindTrim (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + public virtual System.Linq.Expressions.Expression BindUnaryOperatorNode (Microsoft.OData.UriParser.UnaryOperatorNode unaryOperatorNode, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + protected static System.Reflection.PropertyInfo GetDynamicPropertyContainer (Microsoft.OData.UriParser.SingleValueOpenPropertyAccessNode openNode, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + protected System.Linq.Expressions.Expression GetFlattenedPropertyExpression (string propertyPath, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) +} + +[ +ExtensionAttribute(), +] +public sealed class Microsoft.AspNetCore.OData.Query.Expressions.BinderExtensions { + [ + ExtensionAttribute(), + ] + public static System.Collections.IEnumerable ApplyBind (Microsoft.AspNetCore.OData.Query.Expressions.IFilterBinder binder, System.Collections.IEnumerable query, Microsoft.OData.UriParser.FilterClause filterClause, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + + [ + ExtensionAttribute(), + ] + public static System.Linq.Expressions.Expression ApplyBind (Microsoft.AspNetCore.OData.Query.Expressions.IFilterBinder binder, System.Linq.Expressions.Expression source, Microsoft.OData.UriParser.FilterClause filterClause, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + + [ + ExtensionAttribute(), + ] + public static System.Linq.IQueryable ApplyBind (Microsoft.AspNetCore.OData.Query.Expressions.IFilterBinder binder, System.Linq.IQueryable query, Microsoft.OData.UriParser.FilterClause filterClause, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + + [ + ExtensionAttribute(), + ] + public static System.Linq.IQueryable ApplyBind (Microsoft.AspNetCore.OData.Query.Expressions.ISearchBinder binder, System.Linq.IQueryable source, Microsoft.OData.UriParser.SearchClause searchClause, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + + [ + ExtensionAttribute(), + ] + public static System.Linq.IQueryable ApplyBind (Microsoft.AspNetCore.OData.Query.Expressions.ISelectExpandBinder binder, System.Linq.IQueryable source, Microsoft.OData.UriParser.SelectExpandClause selectExpandClause, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + + [ + ExtensionAttribute(), + ] + public static object ApplyBind (Microsoft.AspNetCore.OData.Query.Expressions.ISelectExpandBinder binder, object source, Microsoft.OData.UriParser.SelectExpandClause selectExpandClause, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + + [ + ExtensionAttribute(), + ] + public static System.Linq.Expressions.Expression ApplyBind (Microsoft.AspNetCore.OData.Query.Expressions.IOrderByBinder binder, System.Linq.Expressions.Expression source, Microsoft.OData.UriParser.OrderByClause orderByClause, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context, bool alreadyOrdered) + + [ + ExtensionAttribute(), + ] + public static System.Linq.IQueryable ApplyBind (Microsoft.AspNetCore.OData.Query.Expressions.IOrderByBinder binder, System.Linq.IQueryable query, Microsoft.OData.UriParser.OrderByClause orderByClause, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context, bool alreadyOrdered) +} + +public class Microsoft.AspNetCore.OData.Query.Expressions.FilterBinder : Microsoft.AspNetCore.OData.Query.Expressions.QueryBinder, IFilterBinder { + public FilterBinder () + + public virtual System.Linq.Expressions.Expression BindFilter (Microsoft.OData.UriParser.FilterClause filterClause, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) +} + +public class Microsoft.AspNetCore.OData.Query.Expressions.OrderByBinder : Microsoft.AspNetCore.OData.Query.Expressions.QueryBinder, IOrderByBinder { + public OrderByBinder () + + public virtual Microsoft.AspNetCore.OData.Query.Expressions.OrderByBinderResult BindOrderBy (Microsoft.OData.UriParser.OrderByClause orderByClause, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) +} + +public class Microsoft.AspNetCore.OData.Query.Expressions.OrderByBinderResult { + public OrderByBinderResult (System.Linq.Expressions.Expression orderByExpression, Microsoft.OData.UriParser.OrderByDirection direction) + + Microsoft.OData.UriParser.OrderByDirection Direction { public get; } + System.Linq.Expressions.Expression OrderByExpression { public get; } + Microsoft.AspNetCore.OData.Query.Expressions.OrderByBinderResult ThenBy { public get; public set; } +} + +public class Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext { + public QueryBinderContext (Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context, Microsoft.AspNetCore.OData.Query.ODataQuerySettings querySettings, System.Type clrType) + public QueryBinderContext (Microsoft.OData.Edm.IEdmModel model, Microsoft.AspNetCore.OData.Query.ODataQuerySettings querySettings, System.Type clrType) + + Microsoft.OData.ModelBuilder.IAssemblyResolver AssembliesResolver { public get; public set; } + System.Collections.Generic.IDictionary`2[[System.String],[Microsoft.OData.UriParser.ComputeExpression]] ComputedProperties { public get; } + System.Linq.Expressions.ParameterExpression CurrentParameter { public get; } + System.Type ElementClrType { public get; } + Microsoft.OData.Edm.IEdmType ElementType { public get; } + Microsoft.OData.Edm.IEdmModel Model { public get; } + Microsoft.OData.Edm.IEdmNavigationSource NavigationSource { public get; public set; } + Microsoft.AspNetCore.OData.Query.ODataQuerySettings QuerySettings { public get; } + System.Linq.Expressions.Expression Source { public get; public set; } + + public System.Linq.Expressions.ParameterExpression GetParameter (string name) + public void RemoveParameter (string name) +} + +public class Microsoft.AspNetCore.OData.Query.Expressions.SelectExpandBinder : Microsoft.AspNetCore.OData.Query.Expressions.QueryBinder, ISelectExpandBinder { + public SelectExpandBinder (Microsoft.AspNetCore.OData.Query.Expressions.IFilterBinder filterBinder, Microsoft.AspNetCore.OData.Query.Expressions.IOrderByBinder orderByBinder) + + Microsoft.AspNetCore.OData.Query.Expressions.IFilterBinder FilterBinder { public get; } + Microsoft.AspNetCore.OData.Query.Expressions.IOrderByBinder OrderByBinder { public get; } + + public virtual void BindComputedProperty (System.Linq.Expressions.Expression source, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context, string computedProperty, System.Collections.Generic.IList`1[[Microsoft.AspNetCore.OData.Query.Container.NamedPropertyExpression]] includedProperties) + public virtual System.Linq.Expressions.Expression BindSelectExpand (Microsoft.OData.UriParser.SelectExpandClause selectExpandClause, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context) + public virtual void BuildDynamicProperty (Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context, System.Linq.Expressions.Expression source, Microsoft.OData.Edm.IEdmStructuredType structuredType, System.Collections.Generic.IList`1[[Microsoft.AspNetCore.OData.Query.Container.NamedPropertyExpression]] includedProperties) + public virtual System.Linq.Expressions.Expression CreatePropertyNameExpression (Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context, Microsoft.OData.Edm.IEdmStructuredType elementType, Microsoft.OData.Edm.IEdmProperty edmProperty, System.Linq.Expressions.Expression source) + public virtual System.Linq.Expressions.Expression CreatePropertyValueExpression (Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context, Microsoft.OData.Edm.IEdmStructuredType elementType, Microsoft.OData.Edm.IEdmProperty edmProperty, System.Linq.Expressions.Expression source, Microsoft.OData.UriParser.FilterClause filterClause, params Microsoft.OData.UriParser.ComputeClause computeClause) + public virtual System.Linq.Expressions.Expression CreateTotalCountExpression (Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context, System.Linq.Expressions.Expression source, System.Nullable`1[[System.Boolean]] countOption) + public virtual System.Linq.Expressions.Expression CreateTypeNameExpression (System.Linq.Expressions.Expression source, Microsoft.OData.Edm.IEdmStructuredType elementType, Microsoft.OData.Edm.IEdmModel model) +} + +public class Microsoft.AspNetCore.OData.Query.Validator.CountQueryValidator { + public CountQueryValidator () + + public virtual void Validate (Microsoft.AspNetCore.OData.Query.CountQueryOption countQueryOption, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings validationSettings) +} + +public class Microsoft.AspNetCore.OData.Query.Validator.FilterQueryValidator { + public FilterQueryValidator () + + public virtual void Validate (Microsoft.AspNetCore.OData.Query.FilterQueryOption filterQueryOption, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings settings) + public virtual void Validate (Microsoft.OData.UriParser.FilterClause filterClause, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings settings, Microsoft.OData.Edm.IEdmModel model) + internal virtual void Validate (Microsoft.OData.Edm.IEdmProperty property, Microsoft.OData.Edm.IEdmStructuredType structuredType, Microsoft.OData.UriParser.FilterClause filterClause, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings settings, Microsoft.OData.Edm.IEdmModel model, Microsoft.OData.ModelBuilder.Config.DefaultQuerySettings querySettings) + protected virtual void ValidateAllNode (Microsoft.OData.UriParser.AllNode allNode, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings settings) + protected virtual void ValidateAnyNode (Microsoft.OData.UriParser.AnyNode anyNode, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings settings) + protected virtual void ValidateArithmeticOperator (Microsoft.OData.UriParser.BinaryOperatorNode binaryNode, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings settings) + protected virtual void ValidateBinaryOperatorNode (Microsoft.OData.UriParser.BinaryOperatorNode binaryOperatorNode, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings settings) + protected virtual void ValidateCollectionComplexNode (Microsoft.OData.UriParser.CollectionComplexNode collectionComplexNode, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings settings) + protected virtual void ValidateCollectionPropertyAccessNode (Microsoft.OData.UriParser.CollectionPropertyAccessNode propertyAccessNode, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings settings) + protected virtual void ValidateCollectionResourceCastNode (Microsoft.OData.UriParser.CollectionResourceCastNode collectionResourceCastNode, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings settings) + protected virtual void ValidateConstantNode (Microsoft.OData.UriParser.ConstantNode constantNode, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings settings) + protected virtual void ValidateConvertNode (Microsoft.OData.UriParser.ConvertNode convertNode, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings settings) + protected virtual void ValidateCountNode (Microsoft.OData.UriParser.CountNode countNode, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings settings) + protected virtual void ValidateLogicalOperator (Microsoft.OData.UriParser.BinaryOperatorNode binaryNode, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings settings) + protected virtual void ValidateNavigationPropertyNode (Microsoft.OData.UriParser.QueryNode sourceNode, Microsoft.OData.Edm.IEdmNavigationProperty navigationProperty, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings settings) + protected virtual void ValidateQueryNode (Microsoft.OData.UriParser.QueryNode node, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings settings) + protected virtual void ValidateRangeVariable (Microsoft.OData.UriParser.RangeVariable rangeVariable, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings settings) + protected virtual void ValidateSingleComplexNode (Microsoft.OData.UriParser.SingleComplexNode singleComplexNode, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings settings) + protected virtual void ValidateSingleResourceCastNode (Microsoft.OData.UriParser.SingleResourceCastNode singleResourceCastNode, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings settings) + protected virtual void ValidateSingleResourceFunctionCallNode (Microsoft.OData.UriParser.SingleResourceFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings settings) + protected virtual void ValidateSingleValueFunctionCallNode (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings settings) + protected virtual void ValidateSingleValuePropertyAccessNode (Microsoft.OData.UriParser.SingleValuePropertyAccessNode propertyAccessNode, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings settings) + protected virtual void ValidateUnaryOperatorNode (Microsoft.OData.UriParser.UnaryOperatorNode unaryOperatorNode, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings settings) +} + +public class Microsoft.AspNetCore.OData.Query.Validator.ODataQueryValidator { + public ODataQueryValidator () + + public virtual void Validate (Microsoft.AspNetCore.OData.Query.ODataQueryOptions options, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings validationSettings) +} + +public class Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings { + public ODataValidationSettings () + + Microsoft.AspNetCore.OData.Query.AllowedArithmeticOperators AllowedArithmeticOperators { public get; public set; } + Microsoft.AspNetCore.OData.Query.AllowedFunctions AllowedFunctions { public get; public set; } + Microsoft.AspNetCore.OData.Query.AllowedLogicalOperators AllowedLogicalOperators { public get; public set; } + System.Collections.Generic.ISet`1[[System.String]] AllowedOrderByProperties { public get; } + Microsoft.AspNetCore.OData.Query.AllowedQueryOptions AllowedQueryOptions { public get; public set; } + int MaxAnyAllExpressionDepth { public get; public set; } + int MaxExpansionDepth { public get; public set; } + int MaxNodeCount { public get; public set; } + int MaxOrderByNodeCount { public get; public set; } + System.Nullable`1[[System.Int32]] MaxSkip { public get; public set; } + System.Nullable`1[[System.Int32]] MaxTop { public get; public set; } +} + +public class Microsoft.AspNetCore.OData.Query.Validator.OrderByQueryValidator { + public OrderByQueryValidator () + + public virtual void Validate (Microsoft.AspNetCore.OData.Query.OrderByQueryOption orderByOption, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings validationSettings) +} + +public class Microsoft.AspNetCore.OData.Query.Validator.SelectExpandQueryValidator { + public SelectExpandQueryValidator () + + public virtual void Validate (Microsoft.AspNetCore.OData.Query.SelectExpandQueryOption selectExpandQueryOption, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings validationSettings) +} + +public class Microsoft.AspNetCore.OData.Query.Validator.SkipQueryValidator { + public SkipQueryValidator () + + public virtual void Validate (Microsoft.AspNetCore.OData.Query.SkipQueryOption skipQueryOption, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings validationSettings) +} + +public class Microsoft.AspNetCore.OData.Query.Validator.SkipTokenQueryValidator { + public SkipTokenQueryValidator () + + public virtual void Validate (Microsoft.AspNetCore.OData.Query.SkipTokenQueryOption skipToken, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings validationSettings) +} + +public class Microsoft.AspNetCore.OData.Query.Validator.TopQueryValidator { + public TopQueryValidator () + + public virtual void Validate (Microsoft.AspNetCore.OData.Query.TopQueryOption topQueryOption, Microsoft.AspNetCore.OData.Query.Validator.ODataValidationSettings validationSettings) +} + +public interface Microsoft.AspNetCore.OData.Query.Wrapper.ISelectExpandWrapper { + System.Collections.Generic.IDictionary`2[[System.String],[System.Object]] ToDictionary () + System.Collections.Generic.IDictionary`2[[System.String],[System.Object]] ToDictionary (System.Func`3[[Microsoft.OData.Edm.IEdmModel],[Microsoft.OData.Edm.IEdmStructuredType],[Microsoft.AspNetCore.OData.Query.Container.IPropertyMapper]] propertyMapperProvider) +} + +public abstract class Microsoft.AspNetCore.OData.Query.Wrapper.DynamicTypeWrapper { + protected DynamicTypeWrapper () + + System.Collections.Generic.Dictionary`2[[System.String],[System.Object]] Values { public abstract get; } + + public virtual bool TryGetPropertyValue (string propertyName, out System.Object& value) +} + +[ +AttributeUsageAttribute(), +] +public class Microsoft.AspNetCore.OData.Routing.Attributes.ODataRouteComponentAttribute : System.Attribute { + public ODataRouteComponentAttribute () + public ODataRouteComponentAttribute (string routePrefix) + + string RoutePrefix { public get; } +} + +[ +AttributeUsageAttribute(), +] +public sealed class Microsoft.AspNetCore.OData.Routing.Attributes.ODataAttributeRoutingAttribute : System.Attribute { + public ODataAttributeRoutingAttribute () +} + +[ +AttributeUsageAttribute(), +] +public sealed class Microsoft.AspNetCore.OData.Routing.Attributes.ODataIgnoredAttribute : System.Attribute { + public ODataIgnoredAttribute () +} + +[ +ODataAttributeRoutingAttribute(), +] +public abstract class Microsoft.AspNetCore.OData.Routing.Controllers.ODataController : Microsoft.AspNetCore.Mvc.ControllerBase { + protected ODataController () + + protected virtual Microsoft.AspNetCore.OData.Results.BadRequestODataResult BadRequest (Microsoft.OData.ODataError odataError) + protected virtual Microsoft.AspNetCore.OData.Results.BadRequestODataResult BadRequest (string message) + protected virtual Microsoft.AspNetCore.OData.Results.ConflictODataResult Conflict (Microsoft.OData.ODataError odataError) + protected virtual Microsoft.AspNetCore.OData.Results.ConflictODataResult Conflict (string message) + protected virtual CreatedODataResult`1 Created (TEntity entity) + protected virtual Microsoft.AspNetCore.OData.Results.NotFoundODataResult NotFound (Microsoft.OData.ODataError odataError) + protected virtual Microsoft.AspNetCore.OData.Results.NotFoundODataResult NotFound (string message) + protected virtual Microsoft.AspNetCore.OData.Results.ODataErrorResult ODataErrorResult (Microsoft.OData.ODataError odataError) + protected virtual Microsoft.AspNetCore.OData.Results.ODataErrorResult ODataErrorResult (string errorCode, string message) + protected virtual Microsoft.AspNetCore.OData.Results.UnauthorizedODataResult Unauthorized (Microsoft.OData.ODataError odataError) + protected virtual Microsoft.AspNetCore.OData.Results.UnauthorizedODataResult Unauthorized (string message) + protected virtual Microsoft.AspNetCore.OData.Results.UnprocessableEntityODataResult UnprocessableEntity (Microsoft.OData.ODataError odataError) + protected virtual Microsoft.AspNetCore.OData.Results.UnprocessableEntityODataResult UnprocessableEntity (string message) + protected virtual UpdatedODataResult`1 Updated (TEntity entity) +} + +public class Microsoft.AspNetCore.OData.Routing.Controllers.MetadataController : Microsoft.AspNetCore.Mvc.ControllerBase { + public MetadataController () + + [ + HttpGetAttribute(), + ] + public Microsoft.OData.Edm.IEdmModel GetMetadata () + + [ + HttpGetAttribute(), + ] + public Microsoft.OData.ODataServiceDocument GetServiceDocument () +} + +public interface Microsoft.AspNetCore.OData.Routing.Conventions.IODataControllerActionConvention { + int Order { public abstract get; } + + bool AppliesToAction (Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) + bool AppliesToController (Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) +} + +public abstract class Microsoft.AspNetCore.OData.Routing.Conventions.OperationRoutingConvention : IODataControllerActionConvention { + protected OperationRoutingConvention () + + int Order { public abstract get; } + + protected static void AddSelector (Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context, Microsoft.OData.Edm.IEdmOperation edmOperation, bool hasKeyParameter, Microsoft.OData.Edm.IEdmEntityType entityType, Microsoft.OData.Edm.IEdmNavigationSource navigationSource, Microsoft.OData.Edm.IEdmEntityType castType) + public abstract bool AppliesToAction (Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) + public virtual bool AppliesToController (Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) + protected abstract bool IsOperationParameterMatched (Microsoft.OData.Edm.IEdmOperation operation, Microsoft.AspNetCore.Mvc.ApplicationModels.ActionModel action) + protected void ProcessOperations (Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context, Microsoft.OData.Edm.IEdmEntityType entityType, Microsoft.OData.Edm.IEdmNavigationSource navigationSource) +} + +public class Microsoft.AspNetCore.OData.Routing.Conventions.ActionRoutingConvention : Microsoft.AspNetCore.OData.Routing.Conventions.OperationRoutingConvention, IODataControllerActionConvention { + public ActionRoutingConvention () + + int Order { public virtual get; } + + public virtual bool AppliesToAction (Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) + protected virtual bool IsOperationParameterMatched (Microsoft.OData.Edm.IEdmOperation operation, Microsoft.AspNetCore.Mvc.ApplicationModels.ActionModel action) +} + +public class Microsoft.AspNetCore.OData.Routing.Conventions.AttributeRoutingConvention : IODataControllerActionConvention { + public AttributeRoutingConvention (Microsoft.Extensions.Logging.ILogger`1[[Microsoft.AspNetCore.OData.Routing.Conventions.AttributeRoutingConvention]] logger, Microsoft.AspNetCore.OData.Routing.Parser.IODataPathTemplateParser parser) + + int Order { public virtual get; } + + public virtual bool AppliesToAction (Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) + public virtual bool AppliesToController (Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) +} + +public class Microsoft.AspNetCore.OData.Routing.Conventions.EntityRoutingConvention : IODataControllerActionConvention { + public EntityRoutingConvention () + + int Order { public virtual get; } + + public virtual bool AppliesToAction (Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) + public virtual bool AppliesToController (Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) +} + +public class Microsoft.AspNetCore.OData.Routing.Conventions.EntitySetRoutingConvention : IODataControllerActionConvention { + public EntitySetRoutingConvention () + + int Order { public virtual get; } + + public virtual bool AppliesToAction (Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) + public virtual bool AppliesToController (Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) +} + +public class Microsoft.AspNetCore.OData.Routing.Conventions.FunctionRoutingConvention : Microsoft.AspNetCore.OData.Routing.Conventions.OperationRoutingConvention, IODataControllerActionConvention { + public FunctionRoutingConvention () + + int Order { public virtual get; } + + public virtual bool AppliesToAction (Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) + protected virtual bool IsOperationParameterMatched (Microsoft.OData.Edm.IEdmOperation operation, Microsoft.AspNetCore.Mvc.ApplicationModels.ActionModel action) +} + +public class Microsoft.AspNetCore.OData.Routing.Conventions.MetadataRoutingConvention : IODataControllerActionConvention { + public MetadataRoutingConvention () + + int Order { public virtual get; } + + public virtual bool AppliesToAction (Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) + public virtual bool AppliesToController (Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) +} + +public class Microsoft.AspNetCore.OData.Routing.Conventions.NavigationRoutingConvention : IODataControllerActionConvention { + public NavigationRoutingConvention (Microsoft.Extensions.Logging.ILogger`1[[Microsoft.AspNetCore.OData.Routing.Conventions.NavigationRoutingConvention]] logger) + + int Order { public virtual get; } + + public virtual bool AppliesToAction (Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) + public virtual bool AppliesToController (Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) +} + +public class Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext { + public ODataControllerActionContext (string prefix, Microsoft.OData.Edm.IEdmModel model, Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerModel controller) + + Microsoft.AspNetCore.Mvc.ApplicationModels.ActionModel Action { public get; public set; } + Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerModel Controller { public get; } + Microsoft.OData.Edm.IEdmEntitySet EntitySet { public get; } + Microsoft.OData.Edm.IEdmEntityType EntityType { public get; } + Microsoft.OData.Edm.IEdmModel Model { public get; } + Microsoft.OData.Edm.IEdmNavigationSource NavigationSource { public get; public set; } + Microsoft.AspNetCore.OData.ODataOptions Options { public get; public set; } + string Prefix { public get; } + Microsoft.OData.Edm.IEdmSingleton Singleton { public get; } +} + +public class Microsoft.AspNetCore.OData.Routing.Conventions.OperationImportRoutingConvention : IODataControllerActionConvention { + public OperationImportRoutingConvention () + + int Order { public virtual get; } + + public virtual bool AppliesToAction (Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) + public virtual bool AppliesToController (Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) +} + +public class Microsoft.AspNetCore.OData.Routing.Conventions.PropertyRoutingConvention : IODataControllerActionConvention { + public PropertyRoutingConvention () + + int Order { public virtual get; } + + public virtual bool AppliesToAction (Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) + public virtual bool AppliesToController (Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) +} + +public class Microsoft.AspNetCore.OData.Routing.Conventions.RefRoutingConvention : IODataControllerActionConvention { + public RefRoutingConvention () + + int Order { public virtual get; } + + public virtual bool AppliesToAction (Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) + public virtual bool AppliesToController (Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) +} + +public class Microsoft.AspNetCore.OData.Routing.Conventions.SingletonRoutingConvention : IODataControllerActionConvention { + public SingletonRoutingConvention () + + int Order { public virtual get; } + + public virtual bool AppliesToAction (Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) + public virtual bool AppliesToController (Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) +} + +public interface Microsoft.AspNetCore.OData.Routing.Parser.IODataPathTemplateParser { + Microsoft.AspNetCore.OData.Routing.Template.ODataPathTemplate Parse (Microsoft.OData.Edm.IEdmModel model, string odataPath, System.IServiceProvider requestProvider) +} + +public class Microsoft.AspNetCore.OData.Routing.Parser.DefaultODataPathTemplateParser : IODataPathTemplateParser { + public DefaultODataPathTemplateParser () + + public virtual Microsoft.AspNetCore.OData.Routing.Template.ODataPathTemplate Parse (Microsoft.OData.Edm.IEdmModel model, string odataPath, System.IServiceProvider requestProvider) +} + +public interface Microsoft.AspNetCore.OData.Routing.Template.IODataTemplateTranslator { + Microsoft.OData.UriParser.ODataPath Translate (Microsoft.AspNetCore.OData.Routing.Template.ODataPathTemplate path, Microsoft.AspNetCore.OData.Routing.Template.ODataTemplateTranslateContext context) +} + +public abstract class Microsoft.AspNetCore.OData.Routing.Template.ODataSegmentTemplate { + protected ODataSegmentTemplate () + + public abstract System.Collections.Generic.IEnumerable`1[[System.String]] GetTemplates (Microsoft.AspNetCore.OData.Routing.ODataRouteOptions options) + public abstract bool TryTranslate (Microsoft.AspNetCore.OData.Routing.Template.ODataTemplateTranslateContext context) +} + +public class Microsoft.AspNetCore.OData.Routing.Template.ActionImportSegmentTemplate : Microsoft.AspNetCore.OData.Routing.Template.ODataSegmentTemplate { + public ActionImportSegmentTemplate (Microsoft.OData.UriParser.OperationImportSegment segment) + public ActionImportSegmentTemplate (Microsoft.OData.Edm.IEdmActionImport actionImport, Microsoft.OData.Edm.IEdmNavigationSource navigationSource) + + Microsoft.OData.Edm.IEdmActionImport ActionImport { public get; } + Microsoft.OData.UriParser.OperationImportSegment Segment { public get; } + + public virtual System.Collections.Generic.IEnumerable`1[[System.String]] GetTemplates (Microsoft.AspNetCore.OData.Routing.ODataRouteOptions options) + public virtual bool TryTranslate (Microsoft.AspNetCore.OData.Routing.Template.ODataTemplateTranslateContext context) +} + +public class Microsoft.AspNetCore.OData.Routing.Template.ActionSegmentTemplate : Microsoft.AspNetCore.OData.Routing.Template.ODataSegmentTemplate { + public ActionSegmentTemplate (Microsoft.OData.UriParser.OperationSegment segment) + public ActionSegmentTemplate (Microsoft.OData.Edm.IEdmAction action, Microsoft.OData.Edm.IEdmNavigationSource navigationSource) + + Microsoft.OData.Edm.IEdmAction Action { public get; } + Microsoft.OData.Edm.IEdmNavigationSource NavigationSource { public get; } + Microsoft.OData.UriParser.OperationSegment Segment { public get; } + + public virtual System.Collections.Generic.IEnumerable`1[[System.String]] GetTemplates (Microsoft.AspNetCore.OData.Routing.ODataRouteOptions options) + public virtual bool TryTranslate (Microsoft.AspNetCore.OData.Routing.Template.ODataTemplateTranslateContext context) +} + +public class Microsoft.AspNetCore.OData.Routing.Template.CastSegmentTemplate : Microsoft.AspNetCore.OData.Routing.Template.ODataSegmentTemplate { + public CastSegmentTemplate (Microsoft.OData.UriParser.TypeSegment typeSegment) + public CastSegmentTemplate (Microsoft.OData.Edm.IEdmType castType, Microsoft.OData.Edm.IEdmType expectedType, Microsoft.OData.Edm.IEdmNavigationSource navigationSource) + + Microsoft.OData.Edm.IEdmType CastType { public get; } + Microsoft.OData.Edm.IEdmType ExpectedType { public get; } + Microsoft.OData.UriParser.TypeSegment TypeSegment { public get; } + + public virtual System.Collections.Generic.IEnumerable`1[[System.String]] GetTemplates (Microsoft.AspNetCore.OData.Routing.ODataRouteOptions options) + public virtual bool TryTranslate (Microsoft.AspNetCore.OData.Routing.Template.ODataTemplateTranslateContext context) +} + +public class Microsoft.AspNetCore.OData.Routing.Template.CountSegmentTemplate : Microsoft.AspNetCore.OData.Routing.Template.ODataSegmentTemplate { + Microsoft.AspNetCore.OData.Routing.Template.CountSegmentTemplate Instance { public static get; } + + public virtual System.Collections.Generic.IEnumerable`1[[System.String]] GetTemplates (Microsoft.AspNetCore.OData.Routing.ODataRouteOptions options) + public virtual bool TryTranslate (Microsoft.AspNetCore.OData.Routing.Template.ODataTemplateTranslateContext context) +} + +public class Microsoft.AspNetCore.OData.Routing.Template.DynamicSegmentTemplate : Microsoft.AspNetCore.OData.Routing.Template.ODataSegmentTemplate { + public DynamicSegmentTemplate (Microsoft.OData.UriParser.DynamicPathSegment segment) + + Microsoft.OData.UriParser.DynamicPathSegment Segment { public get; } + + public virtual System.Collections.Generic.IEnumerable`1[[System.String]] GetTemplates (Microsoft.AspNetCore.OData.Routing.ODataRouteOptions options) + public virtual bool TryTranslate (Microsoft.AspNetCore.OData.Routing.Template.ODataTemplateTranslateContext context) +} + +public class Microsoft.AspNetCore.OData.Routing.Template.EntitySetSegmentTemplate : Microsoft.AspNetCore.OData.Routing.Template.ODataSegmentTemplate { + public EntitySetSegmentTemplate (Microsoft.OData.Edm.IEdmEntitySet entitySet) + public EntitySetSegmentTemplate (Microsoft.OData.UriParser.EntitySetSegment segment) + + Microsoft.OData.Edm.IEdmEntitySet EntitySet { public get; } + Microsoft.OData.UriParser.EntitySetSegment Segment { public get; } + + public virtual System.Collections.Generic.IEnumerable`1[[System.String]] GetTemplates (Microsoft.AspNetCore.OData.Routing.ODataRouteOptions options) + public virtual bool TryTranslate (Microsoft.AspNetCore.OData.Routing.Template.ODataTemplateTranslateContext context) +} + +public class Microsoft.AspNetCore.OData.Routing.Template.FunctionImportSegmentTemplate : Microsoft.AspNetCore.OData.Routing.Template.ODataSegmentTemplate { + public FunctionImportSegmentTemplate (Microsoft.OData.UriParser.OperationImportSegment segment) + public FunctionImportSegmentTemplate (Microsoft.OData.Edm.IEdmFunctionImport functionImport, Microsoft.OData.Edm.IEdmNavigationSource navigationSource) + public FunctionImportSegmentTemplate (System.Collections.Generic.IDictionary`2[[System.String],[System.String]] parameters, Microsoft.OData.Edm.IEdmFunctionImport functionImport, Microsoft.OData.Edm.IEdmNavigationSource navigationSource) + + Microsoft.OData.Edm.IEdmFunctionImport FunctionImport { public get; } + Microsoft.OData.Edm.IEdmNavigationSource NavigationSource { public get; } + System.Collections.Generic.IDictionary`2[[System.String],[System.String]] ParameterMappings { public get; } + + public virtual System.Collections.Generic.IEnumerable`1[[System.String]] GetTemplates (Microsoft.AspNetCore.OData.Routing.ODataRouteOptions options) + public virtual bool TryTranslate (Microsoft.AspNetCore.OData.Routing.Template.ODataTemplateTranslateContext context) +} + +public class Microsoft.AspNetCore.OData.Routing.Template.FunctionSegmentTemplate : Microsoft.AspNetCore.OData.Routing.Template.ODataSegmentTemplate { + public FunctionSegmentTemplate (Microsoft.OData.UriParser.OperationSegment operationSegment) + public FunctionSegmentTemplate (Microsoft.OData.Edm.IEdmFunction function, Microsoft.OData.Edm.IEdmNavigationSource navigationSource) + public FunctionSegmentTemplate (System.Collections.Generic.IDictionary`2[[System.String],[System.String]] parameters, Microsoft.OData.Edm.IEdmFunction function, Microsoft.OData.Edm.IEdmNavigationSource navigationSource) + + Microsoft.OData.Edm.IEdmFunction Function { public get; } + Microsoft.OData.Edm.IEdmNavigationSource NavigationSource { public get; } + System.Collections.Generic.IDictionary`2[[System.String],[System.String]] ParameterMappings { public get; } + + public virtual System.Collections.Generic.IEnumerable`1[[System.String]] GetTemplates (Microsoft.AspNetCore.OData.Routing.ODataRouteOptions options) + public virtual bool TryTranslate (Microsoft.AspNetCore.OData.Routing.Template.ODataTemplateTranslateContext context) +} + +public class Microsoft.AspNetCore.OData.Routing.Template.KeySegmentTemplate : Microsoft.AspNetCore.OData.Routing.Template.ODataSegmentTemplate { + public KeySegmentTemplate (Microsoft.OData.UriParser.KeySegment segment) + public KeySegmentTemplate (Microsoft.OData.UriParser.KeySegment segment, System.Collections.Generic.IDictionary`2[[System.String],[Microsoft.OData.Edm.IEdmProperty]] keyProperties) + public KeySegmentTemplate (System.Collections.Generic.IDictionary`2[[System.String],[System.String]] keys, Microsoft.OData.Edm.IEdmEntityType entityType, Microsoft.OData.Edm.IEdmNavigationSource navigationSource) + + int Count { public get; } + Microsoft.OData.Edm.IEdmEntityType EntityType { public get; } + System.Collections.Generic.IDictionary`2[[System.String],[System.String]] KeyMappings { public get; } + System.Collections.Generic.IDictionary`2[[System.String],[Microsoft.OData.Edm.IEdmProperty]] KeyProperties { public get; } + Microsoft.OData.Edm.IEdmNavigationSource NavigationSource { public get; } + + public virtual System.Collections.Generic.IEnumerable`1[[System.String]] GetTemplates (Microsoft.AspNetCore.OData.Routing.ODataRouteOptions options) + public virtual bool TryTranslate (Microsoft.AspNetCore.OData.Routing.Template.ODataTemplateTranslateContext context) +} + +public class Microsoft.AspNetCore.OData.Routing.Template.MetadataSegmentTemplate : Microsoft.AspNetCore.OData.Routing.Template.ODataSegmentTemplate { + Microsoft.AspNetCore.OData.Routing.Template.MetadataSegmentTemplate Instance { public static get; } + + public virtual System.Collections.Generic.IEnumerable`1[[System.String]] GetTemplates (Microsoft.AspNetCore.OData.Routing.ODataRouteOptions options) + public virtual bool TryTranslate (Microsoft.AspNetCore.OData.Routing.Template.ODataTemplateTranslateContext context) +} + +public class Microsoft.AspNetCore.OData.Routing.Template.NavigationLinkSegmentTemplate : Microsoft.AspNetCore.OData.Routing.Template.ODataSegmentTemplate { + public NavigationLinkSegmentTemplate (Microsoft.OData.UriParser.NavigationPropertyLinkSegment segment) + public NavigationLinkSegmentTemplate (Microsoft.OData.Edm.IEdmNavigationProperty navigationProperty, Microsoft.OData.Edm.IEdmNavigationSource navigationSource) + + Microsoft.AspNetCore.OData.Routing.Template.KeySegmentTemplate Key { public get; public set; } + Microsoft.OData.Edm.IEdmNavigationProperty NavigationProperty { public get; } + Microsoft.OData.Edm.IEdmNavigationSource NavigationSource { public get; } + Microsoft.OData.UriParser.NavigationPropertyLinkSegment Segment { public get; } + + public virtual System.Collections.Generic.IEnumerable`1[[System.String]] GetTemplates (Microsoft.AspNetCore.OData.Routing.ODataRouteOptions options) + public virtual bool TryTranslate (Microsoft.AspNetCore.OData.Routing.Template.ODataTemplateTranslateContext context) +} + +public class Microsoft.AspNetCore.OData.Routing.Template.NavigationLinkTemplateSegmentTemplate : Microsoft.AspNetCore.OData.Routing.Template.ODataSegmentTemplate { + public NavigationLinkTemplateSegmentTemplate (Microsoft.OData.Edm.IEdmStructuredType declaringType, Microsoft.OData.Edm.IEdmNavigationSource navigationSource) + + Microsoft.OData.Edm.IEdmStructuredType DeclaringType { public get; } + Microsoft.OData.Edm.IEdmNavigationSource NavigationSource { public get; } + string RelatedKey { public get; public set; } + + public virtual System.Collections.Generic.IEnumerable`1[[System.String]] GetTemplates (Microsoft.AspNetCore.OData.Routing.ODataRouteOptions options) + public virtual bool TryTranslate (Microsoft.AspNetCore.OData.Routing.Template.ODataTemplateTranslateContext context) +} + +public class Microsoft.AspNetCore.OData.Routing.Template.NavigationSegmentTemplate : Microsoft.AspNetCore.OData.Routing.Template.ODataSegmentTemplate { + public NavigationSegmentTemplate (Microsoft.OData.UriParser.NavigationPropertySegment segment) + public NavigationSegmentTemplate (Microsoft.OData.Edm.IEdmNavigationProperty navigationProperty, Microsoft.OData.Edm.IEdmNavigationSource navigationSource) + + Microsoft.OData.Edm.IEdmNavigationProperty NavigationProperty { public get; } + Microsoft.OData.UriParser.NavigationPropertySegment Segment { public get; } + + public virtual System.Collections.Generic.IEnumerable`1[[System.String]] GetTemplates (Microsoft.AspNetCore.OData.Routing.ODataRouteOptions options) + public virtual bool TryTranslate (Microsoft.AspNetCore.OData.Routing.Template.ODataTemplateTranslateContext context) +} + +public class Microsoft.AspNetCore.OData.Routing.Template.ODataPathTemplate : System.Collections.Generic.List`1[[Microsoft.AspNetCore.OData.Routing.Template.ODataSegmentTemplate]], ICollection, IEnumerable, IList, ICollection`1, IEnumerable`1, IList`1, IReadOnlyCollection`1, IReadOnlyList`1 { + public ODataPathTemplate (Microsoft.AspNetCore.OData.Routing.Template.ODataSegmentTemplate[] segments) + public ODataPathTemplate (System.Collections.Generic.IEnumerable`1[[Microsoft.AspNetCore.OData.Routing.Template.ODataSegmentTemplate]] segments) + public ODataPathTemplate (System.Collections.Generic.IList`1[[Microsoft.AspNetCore.OData.Routing.Template.ODataSegmentTemplate]] segments) + + public virtual System.Collections.Generic.IEnumerable`1[[System.String]] GetTemplates (params Microsoft.AspNetCore.OData.Routing.ODataRouteOptions options) +} + +public class Microsoft.AspNetCore.OData.Routing.Template.ODataTemplateTranslateContext { + public ODataTemplateTranslateContext (Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Http.Endpoint endpoint, Microsoft.AspNetCore.Routing.RouteValueDictionary routeValues, Microsoft.OData.Edm.IEdmModel model) + + Microsoft.AspNetCore.Http.Endpoint Endpoint { public get; } + Microsoft.AspNetCore.Http.HttpContext HttpContext { public get; } + Microsoft.OData.Edm.IEdmModel Model { public get; } + Microsoft.AspNetCore.Routing.RouteValueDictionary RouteValues { public get; } + System.Collections.Generic.IList`1[[Microsoft.OData.UriParser.ODataPathSegment]] Segments { public get; } + Microsoft.AspNetCore.Routing.RouteValueDictionary UpdatedValues { public get; } + + public string GetParameterAliasOrSelf (string alias) +} + +public class Microsoft.AspNetCore.OData.Routing.Template.PathTemplateSegmentTemplate : Microsoft.AspNetCore.OData.Routing.Template.ODataSegmentTemplate { + public PathTemplateSegmentTemplate (Microsoft.OData.UriParser.PathTemplateSegment segment) + + string ParameterName { public get; } + Microsoft.OData.UriParser.PathTemplateSegment Segment { public get; } + + public virtual System.Collections.Generic.IEnumerable`1[[System.String]] GetTemplates (Microsoft.AspNetCore.OData.Routing.ODataRouteOptions options) + public virtual bool TryTranslate (Microsoft.AspNetCore.OData.Routing.Template.ODataTemplateTranslateContext context) +} + +public class Microsoft.AspNetCore.OData.Routing.Template.PropertyCatchAllSegmentTemplate : Microsoft.AspNetCore.OData.Routing.Template.ODataSegmentTemplate { + public PropertyCatchAllSegmentTemplate (Microsoft.OData.Edm.IEdmStructuredType declaredType) + + Microsoft.OData.Edm.IEdmStructuredType StructuredType { public get; } + + public virtual System.Collections.Generic.IEnumerable`1[[System.String]] GetTemplates (Microsoft.AspNetCore.OData.Routing.ODataRouteOptions options) + public virtual bool TryTranslate (Microsoft.AspNetCore.OData.Routing.Template.ODataTemplateTranslateContext context) +} + +public class Microsoft.AspNetCore.OData.Routing.Template.PropertySegmentTemplate : Microsoft.AspNetCore.OData.Routing.Template.ODataSegmentTemplate { + public PropertySegmentTemplate (Microsoft.OData.Edm.IEdmStructuralProperty property) + public PropertySegmentTemplate (Microsoft.OData.UriParser.PropertySegment segment) + + Microsoft.OData.Edm.IEdmStructuralProperty Property { public get; } + Microsoft.OData.UriParser.PropertySegment Segment { public get; } + + public virtual System.Collections.Generic.IEnumerable`1[[System.String]] GetTemplates (Microsoft.AspNetCore.OData.Routing.ODataRouteOptions options) + public virtual bool TryTranslate (Microsoft.AspNetCore.OData.Routing.Template.ODataTemplateTranslateContext context) +} + +public class Microsoft.AspNetCore.OData.Routing.Template.SingletonSegmentTemplate : Microsoft.AspNetCore.OData.Routing.Template.ODataSegmentTemplate { + public SingletonSegmentTemplate (Microsoft.OData.Edm.IEdmSingleton singleton) + public SingletonSegmentTemplate (Microsoft.OData.UriParser.SingletonSegment segment) + + Microsoft.OData.UriParser.SingletonSegment Segment { public get; } + Microsoft.OData.Edm.IEdmSingleton Singleton { public get; } + + public virtual System.Collections.Generic.IEnumerable`1[[System.String]] GetTemplates (Microsoft.AspNetCore.OData.Routing.ODataRouteOptions options) + public virtual bool TryTranslate (Microsoft.AspNetCore.OData.Routing.Template.ODataTemplateTranslateContext context) +} + +public class Microsoft.AspNetCore.OData.Routing.Template.ValueSegmentTemplate : Microsoft.AspNetCore.OData.Routing.Template.ODataSegmentTemplate { + public ValueSegmentTemplate (Microsoft.OData.Edm.IEdmType previousType) + public ValueSegmentTemplate (Microsoft.OData.UriParser.ValueSegment segment) + + Microsoft.OData.UriParser.ValueSegment Segment { public get; } + + public virtual System.Collections.Generic.IEnumerable`1[[System.String]] GetTemplates (Microsoft.AspNetCore.OData.Routing.ODataRouteOptions options) + public virtual bool TryTranslate (Microsoft.AspNetCore.OData.Routing.Template.ODataTemplateTranslateContext context) +} + diff --git a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.NetCore31.bsl b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.NetCore31.bsl index 87b1c80ee..33c7d45d6 100644 --- a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.NetCore31.bsl +++ b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.NetCore31.bsl @@ -1575,6 +1575,10 @@ public sealed class Microsoft.AspNetCore.OData.Query.ODataQueryParameterBindingA public ODataQueryParameterBindingAttribute () } +public interface Microsoft.AspNetCore.OData.Results.IODataErrorResult { + Microsoft.OData.ODataError Error { public abstract get; } +} + [ DataContractAttribute(), ] @@ -1602,6 +1606,30 @@ public abstract class Microsoft.AspNetCore.OData.Results.SingleResult { public static SingleResult`1 Create (IQueryable`1 queryable) } +public class Microsoft.AspNetCore.OData.Results.BadRequestODataResult : Microsoft.AspNetCore.Mvc.BadRequestResult, IActionResult, IClientErrorActionResult, IStatusCodeActionResult, IODataErrorResult { + public BadRequestODataResult (Microsoft.OData.ODataError odataError) + public BadRequestODataResult (string message) + + Microsoft.OData.ODataError Error { public virtual get; } + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task ExecuteResultAsync (Microsoft.AspNetCore.Mvc.ActionContext context) +} + +public class Microsoft.AspNetCore.OData.Results.ConflictODataResult : Microsoft.AspNetCore.Mvc.ConflictResult, IActionResult, IClientErrorActionResult, IStatusCodeActionResult, IODataErrorResult { + public ConflictODataResult (Microsoft.OData.ODataError odataError) + public ConflictODataResult (string message) + + Microsoft.OData.ODataError Error { public virtual get; } + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task ExecuteResultAsync (Microsoft.AspNetCore.Mvc.ActionContext context) +} + public class Microsoft.AspNetCore.OData.Results.CreatedODataResult`1 : Microsoft.AspNetCore.Mvc.ActionResult, IActionResult { public CreatedODataResult`1 (T entity) @@ -1613,6 +1641,30 @@ public class Microsoft.AspNetCore.OData.Results.CreatedODataResult`1 : Microsoft public virtual System.Threading.Tasks.Task ExecuteResultAsync (Microsoft.AspNetCore.Mvc.ActionContext context) } +public class Microsoft.AspNetCore.OData.Results.NotFoundODataResult : Microsoft.AspNetCore.Mvc.NotFoundResult, IActionResult, IClientErrorActionResult, IStatusCodeActionResult, IODataErrorResult { + public NotFoundODataResult (Microsoft.OData.ODataError odataError) + public NotFoundODataResult (string message) + + Microsoft.OData.ODataError Error { public virtual get; } + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task ExecuteResultAsync (Microsoft.AspNetCore.Mvc.ActionContext context) +} + +public class Microsoft.AspNetCore.OData.Results.ODataErrorResult : Microsoft.AspNetCore.Mvc.ActionResult, IActionResult, IODataErrorResult { + public ODataErrorResult (Microsoft.OData.ODataError odataError) + public ODataErrorResult (string errorCode, string message) + + Microsoft.OData.ODataError Error { public virtual get; } + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task ExecuteResultAsync (Microsoft.AspNetCore.Mvc.ActionContext context) +} + [ DataContractAttribute(), ] @@ -1629,6 +1681,30 @@ public class Microsoft.AspNetCore.OData.Results.PageResult`1 : Microsoft.AspNetC public virtual System.Collections.Generic.IDictionary`2[[System.String],[System.Object]] ToDictionary () } +public class Microsoft.AspNetCore.OData.Results.UnauthorizedODataResult : Microsoft.AspNetCore.Mvc.UnauthorizedResult, IActionResult, IClientErrorActionResult, IStatusCodeActionResult, IODataErrorResult { + public UnauthorizedODataResult (Microsoft.OData.ODataError odataError) + public UnauthorizedODataResult (string message) + + Microsoft.OData.ODataError Error { public virtual get; } + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task ExecuteResultAsync (Microsoft.AspNetCore.Mvc.ActionContext context) +} + +public class Microsoft.AspNetCore.OData.Results.UnprocessableEntityODataResult : Microsoft.AspNetCore.Mvc.UnprocessableEntityResult, IActionResult, IClientErrorActionResult, IStatusCodeActionResult, IODataErrorResult { + public UnprocessableEntityODataResult (Microsoft.OData.ODataError odataError) + public UnprocessableEntityODataResult (string message) + + Microsoft.OData.ODataError Error { public virtual get; } + + [ + AsyncStateMachineAttribute(), + ] + public virtual System.Threading.Tasks.Task ExecuteResultAsync (Microsoft.AspNetCore.Mvc.ActionContext context) +} + public class Microsoft.AspNetCore.OData.Results.UpdatedODataResult`1 : Microsoft.AspNetCore.Mvc.ActionResult, IActionResult { public UpdatedODataResult`1 (T entity) @@ -2882,7 +2958,19 @@ ODataAttributeRoutingAttribute(), public abstract class Microsoft.AspNetCore.OData.Routing.Controllers.ODataController : Microsoft.AspNetCore.Mvc.ControllerBase { protected ODataController () + protected virtual Microsoft.AspNetCore.OData.Results.BadRequestODataResult BadRequest (Microsoft.OData.ODataError odataError) + protected virtual Microsoft.AspNetCore.OData.Results.BadRequestODataResult BadRequest (string message) + protected virtual Microsoft.AspNetCore.OData.Results.ConflictODataResult Conflict (Microsoft.OData.ODataError odataError) + protected virtual Microsoft.AspNetCore.OData.Results.ConflictODataResult Conflict (string message) protected virtual CreatedODataResult`1 Created (TEntity entity) + protected virtual Microsoft.AspNetCore.OData.Results.NotFoundODataResult NotFound (Microsoft.OData.ODataError odataError) + protected virtual Microsoft.AspNetCore.OData.Results.NotFoundODataResult NotFound (string message) + protected virtual Microsoft.AspNetCore.OData.Results.ODataErrorResult ODataErrorResult (Microsoft.OData.ODataError odataError) + protected virtual Microsoft.AspNetCore.OData.Results.ODataErrorResult ODataErrorResult (string errorCode, string message) + protected virtual Microsoft.AspNetCore.OData.Results.UnauthorizedODataResult Unauthorized (Microsoft.OData.ODataError odataError) + protected virtual Microsoft.AspNetCore.OData.Results.UnauthorizedODataResult Unauthorized (string message) + protected virtual Microsoft.AspNetCore.OData.Results.UnprocessableEntityODataResult UnprocessableEntity (Microsoft.OData.ODataError odataError) + protected virtual Microsoft.AspNetCore.OData.Results.UnprocessableEntityODataResult UnprocessableEntity (string message) protected virtual UpdatedODataResult`1 Updated (TEntity entity) } diff --git a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/PublicApiTest.cs b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/PublicApiTest.cs index 682d3d8cb..a55f4eaad 100644 --- a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/PublicApiTest.cs +++ b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/PublicApiTest.cs @@ -18,6 +18,8 @@ public partial class PublicApiTest #if NET5_0 private const string BaseLineFileName = "Microsoft.AspNetCore.OData.PublicApi.Net5.bsl"; +#elif NET6_0 + private const string BaseLineFileName = "Microsoft.AspNetCore.OData.PublicApi.Net6.bsl"; #else private const string BaseLineFileName = "Microsoft.AspNetCore.OData.PublicApi.NetCore31.bsl"; #endif diff --git a/test/Microsoft.AspNetCore.OData.Tests/Query/ODataLevelTests.cs b/test/Microsoft.AspNetCore.OData.Tests/Query/ODataLevelTests.cs index 5e7bcda56..739438669 100644 --- a/test/Microsoft.AspNetCore.OData.Tests/Query/ODataLevelTests.cs +++ b/test/Microsoft.AspNetCore.OData.Tests/Query/ODataLevelTests.cs @@ -71,17 +71,22 @@ public async Task Levels_Throws_ExcceedsMaxExpandLevel() // Arrange string uri = "odata/LevelsEntities?$expand=Parent($levels=20)"; + string expectedResponse = "{\"errorCode\":\"400\",\"message\":" + + "\"The query specified in the URI is not valid. " + + "The request includes a $expand path which is too deep. " + + "The maximum depth allowed is 5. To increase the limit, set the 'MaxExpansionDepth' " + + "property on EnableQueryAttribute or ODataValidationSettings, or set the 'MaxDepth' " + + "property in ExpandAttribute.\"," + + "\"target\":null,\"details\":null,\"innerError\":null,\"instanceAnnotations\":[]," + + "\"typeAnnotation\":null}"; + // Act HttpResponseMessage response = await Client.GetAsync(uri); // Assert Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); string result = await response.Content.ReadAsStringAsync(); - Assert.Equal( - "The query specified in the URI is not valid. The request includes a $expand path which is too deep. " + - "The maximum depth allowed is 5. To increase the limit, set the 'MaxExpansionDepth' property on " + - "EnableQueryAttribute or ODataValidationSettings, or set the 'MaxDepth' property in ExpandAttribute.", - result); + Assert.Equal(expectedResponse, result); } [Fact] From ceac943f34a77e4132e796740b93539bc1dc0851 Mon Sep 17 00:00:00 2001 From: VirusQuartirus Date: Wed, 13 Jul 2022 10:27:48 +0400 Subject: [PATCH 15/21] Check for empty list instead of null value. (#630) * Check for empty list instead of null value. * Added encoding and BOM check test. Co-authored-by: Max Malakhowsky Co-authored-by: John Gathogo --- .../Formatter/ODataOutputFormatter.cs | 3 ++- .../Enums/EnumsTest.cs | 26 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.OData/Formatter/ODataOutputFormatter.cs b/src/Microsoft.AspNetCore.OData/Formatter/ODataOutputFormatter.cs index d664d1df9..d9255bfed 100644 --- a/src/Microsoft.AspNetCore.OData/Formatter/ODataOutputFormatter.cs +++ b/src/Microsoft.AspNetCore.OData/Formatter/ODataOutputFormatter.cs @@ -194,7 +194,8 @@ public override void WriteResponseHeaders(OutputFormatterWriteContext context) // Set the character set. MediaTypeHeaderValue currentContentType = GetContentType(response.Headers[HeaderNames.ContentType].FirstOrDefault()); RequestHeaders requestHeader = request.GetTypedHeaders(); - if (requestHeader != null && requestHeader.AcceptCharset != null) + // Starting from ASP .NET Core 3.0 AcceptCharset returns an empty collection instead of null. + if (requestHeader?.AcceptCharset.Count > 0) { IEnumerable acceptCharsetValues = requestHeader.AcceptCharset.Select(cs => cs.Value.Value); diff --git a/test/Microsoft.AspNetCore.OData.E2E.Tests/Enums/EnumsTest.cs b/test/Microsoft.AspNetCore.OData.E2E.Tests/Enums/EnumsTest.cs index 71e316561..01055c8b3 100644 --- a/test/Microsoft.AspNetCore.OData.E2E.Tests/Enums/EnumsTest.cs +++ b/test/Microsoft.AspNetCore.OData.E2E.Tests/Enums/EnumsTest.cs @@ -178,6 +178,32 @@ public async Task QueryEntitySetCount(string requestUri, int expectedCount) Assert.Equal(expectedCount, int.Parse(count)); } + [Theory] + [InlineData("/convention/Employees/$count", true)] + [InlineData("/convention/Employees/$count", false)] + public async Task QueryEntitySetCountEncoding(string requestUri, bool sendAcceptCharset) + { + // Arrange + await ResetDatasource(); + HttpClient client = CreateClient(); + client.DefaultRequestHeaders.AcceptCharset.Clear(); + if (sendAcceptCharset) + { + client.DefaultRequestHeaders.AcceptCharset.ParseAdd("utf-8"); + } + + // Act + HttpResponseMessage response = await client.GetAsync(requestUri); + + // Assert + Assert.True(response.IsSuccessStatusCode); + var blob = await response.Content.ReadAsByteArrayAsync(); + Assert.Equal("utf-8", response.Content.Headers.ContentType.CharSet, StringComparer.OrdinalIgnoreCase); + var count = Encoding.UTF8.GetString(blob); + Assert.Equal(3, int.Parse(count)); + Assert.False((blob[0] == 0xEF) && (blob[1] == 0xBB) && (blob[2] == 0xBF)); + } + [Theory] [InlineData("/convention/Employees(1)/SkillSet/$count", 2)] [InlineData("/convention/Employees(1)/SkillSet/$count?$filter=$it eq Microsoft.AspNetCore.OData.E2E.Tests.Enums.Skill'Sql'", 1)] From f675f6c6abe2cd10bfa00ce8c4f7dc83b49e1293 Mon Sep 17 00:00:00 2001 From: Giuliano Barberi Date: Thu, 14 Jul 2022 05:05:36 -0700 Subject: [PATCH 16/21] Fixing ArgumentNullException on empty select/expand (#621) Co-authored-by: Giuliano Barberi --- .../Microsoft.AspNetCore.OData.csproj | 2 +- .../Microsoft.AspNetCore.OData.xml | 5 +++ .../Properties/SRResources.Designer.cs | 9 ++++ .../Properties/SRResources.resx | 3 ++ .../Query/ODataQueryOptions.cs | 2 +- .../Query/Query/SelectExpandQueryOption.cs | 42 +++++++------------ .../Query/Validator/ODataQueryValidator.cs | 10 +++++ .../Query/SelectExpandQueryOptionTest.cs | 9 ++-- .../Validator/ODataQueryValidatorTest.cs | 19 +++++++++ 9 files changed, 68 insertions(+), 33 deletions(-) diff --git a/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.csproj b/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.csproj index ccece2167..58885a451 100644 --- a/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.csproj +++ b/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.csproj @@ -2,7 +2,7 @@ netcoreapp3.1;net5.0 - $(TargetFrameworks);net6.0 + $(TargetFrameworks);net6.0 Microsoft.AspNetCore.OData $(OutputPath)$(AssemblyName).xml true diff --git a/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml b/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml index 8bbf63e82..e83049829 100644 --- a/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml +++ b/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml @@ -7234,6 +7234,11 @@ Looks up a localized string similar to 'select' and 'expand' cannot be both null or empty.. + + + Looks up a localized string similar to 'select' and 'expand' cannot be empty or whitespace. Omit the parameter from the query if it is not used.. + + Looks up a localized string similar to $select does not support selections of type '{0}'.. diff --git a/src/Microsoft.AspNetCore.OData/Properties/SRResources.Designer.cs b/src/Microsoft.AspNetCore.OData/Properties/SRResources.Designer.cs index fee7dfc93..31011acb1 100644 --- a/src/Microsoft.AspNetCore.OData/Properties/SRResources.Designer.cs +++ b/src/Microsoft.AspNetCore.OData/Properties/SRResources.Designer.cs @@ -1662,6 +1662,15 @@ internal static string SelectExpandEmptyOrNull { } } + /// + /// Looks up a localized string similar to 'select' and 'expand' cannot be empty or whitespace. Omit the parameter from the query if it is not used.. + /// + internal static string SelectExpandEmptyOrWhitespace { + get { + return ResourceManager.GetString("SelectExpandEmptyOrWhitespace", resourceCulture); + } + } + /// /// Looks up a localized string similar to $select does not support selections of type '{0}'.. /// diff --git a/src/Microsoft.AspNetCore.OData/Properties/SRResources.resx b/src/Microsoft.AspNetCore.OData/Properties/SRResources.resx index 90b303c9b..e43617960 100644 --- a/src/Microsoft.AspNetCore.OData/Properties/SRResources.resx +++ b/src/Microsoft.AspNetCore.OData/Properties/SRResources.resx @@ -729,4 +729,7 @@ Found multiple action imports with same '{0}' name within an entity container.. + + 'select' and 'expand' cannot be empty or whitespace. Omit the parameter from the query if it is not used. + \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.OData/Query/ODataQueryOptions.cs b/src/Microsoft.AspNetCore.OData/Query/ODataQueryOptions.cs index 86dcb3e05..fb03a96f9 100644 --- a/src/Microsoft.AspNetCore.OData/Query/ODataQueryOptions.cs +++ b/src/Microsoft.AspNetCore.OData/Query/ODataQueryOptions.cs @@ -1017,7 +1017,7 @@ private void BuildQueryOptions(IDictionary queryParameters) } } - if (RawValues.Select != null || RawValues.Expand != null) + if (!string.IsNullOrWhiteSpace(RawValues.Select) || !string.IsNullOrWhiteSpace(RawValues.Expand)) { SelectExpand = new SelectExpandQueryOption(RawValues.Select, RawValues.Expand, Context, _queryOptionParser); diff --git a/src/Microsoft.AspNetCore.OData/Query/Query/SelectExpandQueryOption.cs b/src/Microsoft.AspNetCore.OData/Query/Query/SelectExpandQueryOption.cs index 07da21f1f..a8e99595e 100644 --- a/src/Microsoft.AspNetCore.OData/Query/Query/SelectExpandQueryOption.cs +++ b/src/Microsoft.AspNetCore.OData/Query/Query/SelectExpandQueryOption.cs @@ -48,7 +48,7 @@ public SelectExpandQueryOption(string select, string expand, ODataQueryContext c throw Error.ArgumentNull(nameof(context)); } - if (string.IsNullOrEmpty(select) && string.IsNullOrEmpty(expand)) + if (string.IsNullOrWhiteSpace(select) && string.IsNullOrWhiteSpace(expand)) { throw Error.Argument(SRResources.SelectExpandEmptyOrNull); } @@ -60,7 +60,7 @@ public SelectExpandQueryOption(string select, string expand, ODataQueryContext c if (!(context.ElementType is IEdmStructuredType)) { - throw Error.Argument(SRResources.SelectNonStructured, context.ElementType); + throw Error.Argument("context", SRResources.SelectNonStructured, context.ElementType.ToTraceString()); } Context = context; @@ -82,33 +82,19 @@ internal SelectExpandQueryOption( // This constructor is intended for unit testing only. internal SelectExpandQueryOption(string select, string expand, ODataQueryContext context) + : this(select, expand, context, queryOptionParser: context != null + ? new ODataQueryOptionParser( + context.Model, + context.ElementType, + context.NavigationSource, + new Dictionary + { + { "$select", select }, + { "$expand", expand } + }, + context.RequestContainer) + : null) { - if (context == null) - { - throw Error.ArgumentNull(nameof(context)); - } - - if (string.IsNullOrEmpty(select) && string.IsNullOrEmpty(expand)) - { - throw Error.Argument(SRResources.SelectExpandEmptyOrNull); - } - - if (!(context.ElementType is IEdmStructuredType)) - { - throw Error.Argument("context", SRResources.SelectNonStructured, context.ElementType.ToTraceString()); - } - - Context = context; - RawSelect = select; - RawExpand = expand; - Validator = SelectExpandQueryValidator.GetSelectExpandQueryValidator(context); - - _queryOptionParser = new ODataQueryOptionParser( - context.Model, - context.ElementType, - context.NavigationSource, - new Dictionary { { "$select", select }, { "$expand", expand } }, - context.RequestContainer); } /// diff --git a/src/Microsoft.AspNetCore.OData/Query/Validator/ODataQueryValidator.cs b/src/Microsoft.AspNetCore.OData/Query/Validator/ODataQueryValidator.cs index 0a2e0d0d8..31c6373f7 100644 --- a/src/Microsoft.AspNetCore.OData/Query/Validator/ODataQueryValidator.cs +++ b/src/Microsoft.AspNetCore.OData/Query/Validator/ODataQueryValidator.cs @@ -97,11 +97,13 @@ public virtual void Validate(ODataQueryOptions options, ODataValidationSettings if (options.RawValues.Expand != null) { + ValidateNotEmptyOrWhitespace(options.RawValues.Expand); ValidateQueryOptionAllowed(AllowedQueryOptions.Expand, validationSettings.AllowedQueryOptions); } if (options.RawValues.Select != null) { + ValidateNotEmptyOrWhitespace(options.RawValues.Select); ValidateQueryOptionAllowed(AllowedQueryOptions.Select, validationSettings.AllowedQueryOptions); } @@ -139,5 +141,13 @@ private static void ValidateQueryOptionAllowed(AllowedQueryOptions queryOption, throw new ODataException(Error.Format(SRResources.NotAllowedQueryOption, queryOption, "AllowedQueryOptions")); } } + + private static void ValidateNotEmptyOrWhitespace(string rawValue) + { + if (rawValue != null && string.IsNullOrWhiteSpace(rawValue)) + { + throw new ODataException(SRResources.SelectExpandEmptyOrWhitespace); + } + } } } diff --git a/test/Microsoft.AspNetCore.OData.Tests/Query/Query/SelectExpandQueryOptionTest.cs b/test/Microsoft.AspNetCore.OData.Tests/Query/Query/SelectExpandQueryOptionTest.cs index cff51130e..5aae64a7e 100644 --- a/test/Microsoft.AspNetCore.OData.Tests/Query/Query/SelectExpandQueryOptionTest.cs +++ b/test/Microsoft.AspNetCore.OData.Tests/Query/Query/SelectExpandQueryOptionTest.cs @@ -37,8 +37,11 @@ public void Ctor_ThrowsArgumentNull_Context() "context"); } - [Fact] - public void Ctor_ThrowsArgument_IfBothSelectAndExpandAreNull() + [Theory] + [InlineData(null, null)] + [InlineData("", "")] + [InlineData(" ", " ")] + public void Ctor_ThrowsArgument_IfBothSelectAndExpandAreNullOrWhitespace(string select, string expand) { // Arrange _model.Model.SetAnnotationValue(_model.Customer, new ClrTypeAnnotation(typeof(Customer))); @@ -46,7 +49,7 @@ public void Ctor_ThrowsArgument_IfBothSelectAndExpandAreNull() // Act & Assert ExceptionAssert.Throws( - () => new SelectExpandQueryOption(select: null, expand: null, context: context), + () => new SelectExpandQueryOption(select, expand, context: context), "'select' and 'expand' cannot be both null or empty."); } diff --git a/test/Microsoft.AspNetCore.OData.Tests/Query/Validator/ODataQueryValidatorTest.cs b/test/Microsoft.AspNetCore.OData.Tests/Query/Validator/ODataQueryValidatorTest.cs index b12b43301..7db2107d5 100644 --- a/test/Microsoft.AspNetCore.OData.Tests/Query/Validator/ODataQueryValidatorTest.cs +++ b/test/Microsoft.AspNetCore.OData.Tests/Query/Validator/ODataQueryValidatorTest.cs @@ -269,5 +269,24 @@ public void Validate_ValidatesSelectExpandQueryOption_IfItIsNotNull() // Assert selectExpandValidator.Verify(v => v.Validate(option.SelectExpand, settings), Times.Once()); } + + [Theory] + [InlineData("$select=")] + [InlineData("$select= ")] + [InlineData("$expand=")] + [InlineData("$expand= ")] + [InlineData("$select= &$expand= &")] + public void Validate_ValidatesNotEmptyOrWhitespaceSelectExpandQueryOption_IfEmptyOrWhitespace(string query) + { + var expectedMessage = "'select' and 'expand' cannot be empty or whitespace. Omit the parameter from the query if it is not used."; + + // Arrange + var message = RequestFactory.Create("Get", $"http://localhost/?{query}", setupAction: null); + ODataQueryOptions option = new ODataQueryOptions(_context, message); + ODataValidationSettings settings = new ODataValidationSettings(); + + // Act & Assert + ExceptionAssert.Throws(() => _validator.Validate(option, settings), expectedMessage); + } } } From 0feec0ac5ff3f0abf4dc0a9bf016831c8b7627ac Mon Sep 17 00:00:00 2001 From: John Gathogo Date: Wed, 27 Jul 2022 12:34:33 +0300 Subject: [PATCH 17/21] Resolve ContentID in odata.bind annotation (#643) --- .../ODataResourceDeserializer.cs | 44 ++-- .../Batch/ContentIdToLocationMappingTests.cs | 200 ++++++++++++++++++ 2 files changed, 229 insertions(+), 15 deletions(-) create mode 100644 test/Microsoft.AspNetCore.OData.E2E.Tests/Batch/ContentIdToLocationMappingTests.cs diff --git a/src/Microsoft.AspNetCore.OData/Formatter/Deserialization/ODataResourceDeserializer.cs b/src/Microsoft.AspNetCore.OData/Formatter/Deserialization/ODataResourceDeserializer.cs index e99c87358..ce0cc6b6f 100644 --- a/src/Microsoft.AspNetCore.OData/Formatter/Deserialization/ODataResourceDeserializer.cs +++ b/src/Microsoft.AspNetCore.OData/Formatter/Deserialization/ODataResourceDeserializer.cs @@ -14,7 +14,9 @@ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Serialization; +using System.Text.RegularExpressions; using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.OData.Deltas; using Microsoft.AspNetCore.OData.Edm; using Microsoft.AspNetCore.OData.Extensions; @@ -22,6 +24,7 @@ using Microsoft.AspNetCore.OData.Formatter.Wrapper; using Microsoft.AspNetCore.OData.Routing; using Microsoft.AspNetCore.OData.Routing.Parser; +using Microsoft.Extensions.DependencyInjection; using Microsoft.OData; using Microsoft.OData.Edm; using Microsoft.OData.UriParser; @@ -33,6 +36,8 @@ namespace Microsoft.AspNetCore.OData.Formatter.Deserialization /// public class ODataResourceDeserializer : ODataEdmTypeDeserializer { + private static readonly Regex ContentIdReferencePattern = new Regex(@"\$\d", RegexOptions.Compiled); + /// /// Initializes a new instance of the class. /// @@ -376,7 +381,7 @@ public virtual void ApplyNestedProperty(object resource, ODataNestedResourceInfo } IList nestedItems; - var referenceLinks = resourceInfoWrapper.NestedItems.OfType().ToArray(); + ODataEntityReferenceLinkWrapper[] referenceLinks = resourceInfoWrapper.NestedItems.OfType().ToArray(); if (referenceLinks.Length > 0) { // Be noted: @@ -578,7 +583,7 @@ private object ReadNestedResourceInline(ODataResourceWrapper resourceWrapper, IE IEdmStructuredTypeReference structuredType = edmType.AsStructured(); - var nestedReadContext = new ODataDeserializerContext + ODataDeserializerContext nestedReadContext = new ODataDeserializerContext { Path = readContext.Path, Model = readContext.Model, @@ -797,7 +802,7 @@ private static ODataResourceWrapper CreateResourceWrapper(IEdmTypeReference edmP resource.Properties = CreateKeyProperties(refLink.EntityReferenceLink.Url, readContext) ?? Array.Empty(); ODataResourceWrapper resourceWrapper = new ODataResourceWrapper(resource); - foreach (var instanceAnnotation in refLink.EntityReferenceLink.InstanceAnnotations) + foreach (ODataInstanceAnnotation instanceAnnotation in refLink.EntityReferenceLink.InstanceAnnotations) { resource.InstanceAnnotations.Add(instanceAnnotation); } @@ -835,7 +840,7 @@ private ODataResourceWrapper UpdateResourceWrapper(ODataResourceWrapper resource else { IDictionary newPropertiesDic = resourceWrapper.Resource.Properties.ToDictionary(p => p.Name, p => p); - foreach (var key in keys) + foreach (ODataProperty key in keys) { // Logic: if we have the key property, try to keep the key property and get rid of the key value from ID. // Need to double confirm whether it is the right logic? @@ -870,26 +875,35 @@ private static IList CreateKeyProperties(Uri id, ODataDeserialize try { - Uri serviceRootUri = null; - if (id.IsAbsoluteUri) + IEdmModel model = readContext.Model; + HttpRequest request = readContext.Request; + IServiceProvider requestContainer = request.GetRouteServices(); + Uri resolvedId = id; + + string idOriginalString = id.OriginalString; + if (ContentIdReferencePattern.IsMatch(idOriginalString)) { - string serviceRoot = readContext.Request.CreateODataLink(); - serviceRootUri = new Uri(serviceRoot, UriKind.Absolute); + // We can expect request.ODataBatchFeature() to not be null + string resolvedUri = ContentIdHelpers.ResolveContentId( + idOriginalString, + request.ODataBatchFeature().ContentIdMapping); + resolvedId = new Uri(resolvedUri, UriKind.RelativeOrAbsolute); } - var request = readContext.Request; - IEdmModel model = readContext.Model; - - // TODO: shall we use the DI to inject the path parser? - DefaultODataPathParser pathParser = new DefaultODataPathParser(); + Uri serviceRootUri = new Uri(request.CreateODataLink()); + IODataPathParser pathParser = requestContainer?.GetService(); + if (pathParser == null) // Seems like IODataPathParser is NOT injected into DI container by default + { + pathParser = new DefaultODataPathParser(); + } IList properties = null; - var path = pathParser.Parse(model, serviceRootUri, id, request.GetRouteServices()); + ODataPath path = pathParser.Parse(model, serviceRootUri, resolvedId, requestContainer); KeySegment keySegment = path.OfType().LastOrDefault(); if (keySegment != null) { properties = new List(); - foreach (var key in keySegment.Keys) + foreach (KeyValuePair key in keySegment.Keys) { properties.Add(new ODataProperty { diff --git a/test/Microsoft.AspNetCore.OData.E2E.Tests/Batch/ContentIdToLocationMappingTests.cs b/test/Microsoft.AspNetCore.OData.E2E.Tests/Batch/ContentIdToLocationMappingTests.cs new file mode 100644 index 000000000..7cce8a56a --- /dev/null +++ b/test/Microsoft.AspNetCore.OData.E2E.Tests/Batch/ContentIdToLocationMappingTests.cs @@ -0,0 +1,200 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) .NET Foundation and Contributors. All rights reserved. +// See License.txt in the project root for license information. +// +//------------------------------------------------------------------------------ + +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Net; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.OData.Batch; +using Microsoft.AspNetCore.OData.E2E.Tests.Commons; +using Microsoft.AspNetCore.OData.Routing.Controllers; +using Microsoft.AspNetCore.OData.TestCommon; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.OData; +using Microsoft.OData.Edm; +using Microsoft.OData.ModelBuilder; +using Xunit; + +namespace Microsoft.AspNetCore.OData.E2E.Tests.Batch +{ + public class ContentIdToLocationMappingTests : WebApiTestBase + { + private static IEdmModel edmModel; + + public ContentIdToLocationMappingTests(WebApiTestFixture fixture) + : base(fixture) + { + } + + protected static void UpdateConfigureServices(IServiceCollection services) + { + services.ConfigureControllers( + typeof(ContentIdToLocationMappingParentsController), + typeof(ContentIdToLocationMappingChildrenController)); + + edmModel = GetEdmModel(); + services.AddControllers().AddOData(opt => + { + opt.EnableQueryFeatures(); + opt.EnableContinueOnErrorHeader = true; + opt.AddRouteComponents("ContentIdToLocationMapping", edmModel, new DefaultODataBatchHandler()); + }); + } + + protected static void UpdateConfigure(IApplicationBuilder app) + { + app.UseODataBatching(); + app.UseRouting(); + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + }); + } + + protected static IEdmModel GetEdmModel() + { + ODataModelBuilder builder = new ODataConventionModelBuilder(); + builder.EntitySet("ContentIdToLocationMappingParents"); + builder.EntitySet("ContentIdToLocationMappingChildren"); + builder.Namespace = typeof(ContentIdToLocationMappingParent).Namespace; + + return builder.GetEdmModel(); + } + + [Fact] + public async Task CanResolveContentIdInODataBindAnnotationAsync() + { + // Arrange + HttpClient client = CreateClient(); + string serviceBase = $"{client.BaseAddress}ContentIdToLocationMapping"; + string requestUri = $"{serviceBase}/$batch"; + string parentsUri = $"{serviceBase}/ContentIdToLocationMappingParents"; + string childrenUri = $"{serviceBase}/ContentIdToLocationMappingChildren"; + string payload = "{" + + " \"requests\": [" + + " {" + + " \"id\": \"1\"," + + " \"method\": \"POST\"," + + $" \"url\": \"{parentsUri}\"," + + " \"headers\": {" + + " \"OData-Version\": \"4.0\"," + + " \"Content-Type\": \"application/json;odata.metadata=minimal\"," + + " \"Accept\": \"application/json;odata.metadata=minimal\"" + + " }," + + " \"body\": {\"ParentId\":123}" + + " }," + + " {" + + " \"id\": \"2\"," + + " \"method\": \"POST\"," + + $" \"url\": \"{childrenUri}\"," + + " \"headers\": {" + + " \"OData-Version\": \"4.0\"," + + " \"Content-Type\": \"application/json;odata.metadata=minimal\"," + + " \"Accept\": \"application/json;odata.metadata=minimal\"" + + " }," + + " \"body\": {" + + " \"Parent@odata.bind\": \"$1\"" + + " }" + + " }" + + " ]" + + "}"; + + // Act + HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUri); + request.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json")); + request.Content = new StringContent(payload); + request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json"); + HttpResponseMessage response = await client.SendAsync(request); + + // Assert + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + + var stream = await response.Content.ReadAsStreamAsync(); + IODataResponseMessage odataResponseMessage = new ODataMessageWrapper(stream, response.Content.Headers); + int subResponseCount = 0; + using (var messageReader = new ODataMessageReader(odataResponseMessage, new ODataMessageReaderSettings(), edmModel)) + { + var batchReader = messageReader.CreateODataBatchReader(); + while (batchReader.Read()) + { + switch (batchReader.State) + { + case ODataBatchReaderState.Operation: + var operationMessage = batchReader.CreateOperationResponseMessage(); + subResponseCount++; + Assert.Equal(201, operationMessage.StatusCode); + break; + } + } + } + + // NOTE: We assert that $1 is successfully resolved from the controller action + Assert.Equal(2, subResponseCount); + } + } + + public class ContentIdToLocationMappingParentsController : ODataController + { + public ActionResult Post([FromBody] ContentIdToLocationMappingParent parent) + { + return Created(new Uri($"{Request.Scheme}://{Request.Host}{Request.Path}/{parent.ParentId}"), parent); + } + } + + public class ContentIdToLocationMappingChildrenController : ODataController + { + public ActionResult Post([FromBody] ContentIdToLocationMappingChild child) + { + Assert.Equal(123, child.Parent.ParentId); + + return Created(new Uri($"{Request.Scheme}://{Request.Host}{Request.Path}/{child.ChildId}"), child); + } + } + + public class ContentIdToLocationMappingParent + { + public ContentIdToLocationMappingParent() + { + Children = new HashSet(); + } + + [Key] + public int ParentId + { + get; set; + } + + public virtual ICollection Children + { + get; set; + } + } + + public class ContentIdToLocationMappingChild + { + [Key] + public int ChildId + { + get; set; + } + + public int? ParentId + { + get; set; + } + + public virtual ContentIdToLocationMappingParent Parent + { + get; set; + } + } +} From f1db770af97f5d5f0fcaaf207fd441b5c8357496 Mon Sep 17 00:00:00 2001 From: Sam Xu Date: Fri, 5 Aug 2022 10:28:17 -0700 Subject: [PATCH 18/21] Add a IsConventaional flag in routing metadata (#650) * Add a IsConventaional flag in routing metadata * fix the failing public API test --- .../Microsoft.AspNetCore.OData.xml | 40 ++++++++++++------- .../PublicAPI.Unshipped.txt | 3 ++ .../Conventions/AttributeRoutingConvention.cs | 6 ++- .../Routing/IODataRoutingMetadata.cs | 5 +++ .../Routing/ODataRouteDebugMiddleware.cs | 15 ++++++- .../Routing/ODataRoutingMetadata.cs | 5 +++ ...rosoft.AspNetCore.OData.PublicApi.Net5.bsl | 2 + ...rosoft.AspNetCore.OData.PublicApi.Net6.bsl | 2 + ...t.AspNetCore.OData.PublicApi.NetCore31.bsl | 2 + 9 files changed, 63 insertions(+), 17 deletions(-) diff --git a/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml b/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml index e83049829..dc0971029 100644 --- a/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml +++ b/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml @@ -1094,20 +1094,6 @@ The type to test. True if the type is a DateTime; false otherwise. - - - Determine if a type is a . - - The type to test. - True if the type is a DateOnly; false otherwise. - - - - Determine if a type is a . - - The type to test. - True if the type is a TimeOnly; false otherwise. - Determine if a type is a TimeSpan. @@ -12798,6 +12784,11 @@ Gets the OData path template + + + Gets the boolean value indicating whether it's from OData conventional routing, false means from attribute routing. + + Extension methods for . @@ -13258,6 +13249,11 @@ Gets the OData path template + + + Gets or sets a boolean value indicating from odata conventional routing. + + Provides the values of segment kinds for implementations of odata path template. @@ -14386,3 +14382,19 @@ +ummary> + The value segment. + + + + Gets the value segment. + + + + + + + + + + diff --git a/src/Microsoft.AspNetCore.OData/PublicAPI.Unshipped.txt b/src/Microsoft.AspNetCore.OData/PublicAPI.Unshipped.txt index 13bb98de2..3ee9900ec 100644 --- a/src/Microsoft.AspNetCore.OData/PublicAPI.Unshipped.txt +++ b/src/Microsoft.AspNetCore.OData/PublicAPI.Unshipped.txt @@ -1236,6 +1236,7 @@ Microsoft.AspNetCore.OData.Routing.Conventions.SingletonRoutingConvention Microsoft.AspNetCore.OData.Routing.Conventions.SingletonRoutingConvention.AppliesToAction(Microsoft.AspNetCore.OData.Routing.Conventions.ODataControllerActionContext context) -> bool Microsoft.AspNetCore.OData.Routing.Conventions.SingletonRoutingConvention.SingletonRoutingConvention() -> void Microsoft.AspNetCore.OData.Routing.IODataRoutingMetadata +Microsoft.AspNetCore.OData.Routing.IODataRoutingMetadata.IsConventional.get -> bool Microsoft.AspNetCore.OData.Routing.IODataRoutingMetadata.Model.get -> Microsoft.OData.Edm.IEdmModel Microsoft.AspNetCore.OData.Routing.IODataRoutingMetadata.Prefix.get -> string Microsoft.AspNetCore.OData.Routing.IODataRoutingMetadata.Template.get -> Microsoft.AspNetCore.OData.Routing.Template.ODataPathTemplate @@ -1269,6 +1270,8 @@ Microsoft.AspNetCore.OData.Routing.ODataRouteOptions.EnableUnqualifiedOperationC Microsoft.AspNetCore.OData.Routing.ODataRouteOptions.EnableUnqualifiedOperationCall.set -> void Microsoft.AspNetCore.OData.Routing.ODataRouteOptions.ODataRouteOptions() -> void Microsoft.AspNetCore.OData.Routing.ODataRoutingMetadata +Microsoft.AspNetCore.OData.Routing.ODataRoutingMetadata.IsConventional.get -> bool +Microsoft.AspNetCore.OData.Routing.ODataRoutingMetadata.IsConventional.set -> void Microsoft.AspNetCore.OData.Routing.ODataRoutingMetadata.Model.get -> Microsoft.OData.Edm.IEdmModel Microsoft.AspNetCore.OData.Routing.ODataRoutingMetadata.ODataRoutingMetadata(string prefix, Microsoft.OData.Edm.IEdmModel model, Microsoft.AspNetCore.OData.Routing.Template.ODataPathTemplate template) -> void Microsoft.AspNetCore.OData.Routing.ODataRoutingMetadata.Prefix.get -> string diff --git a/src/Microsoft.AspNetCore.OData/Routing/Conventions/AttributeRoutingConvention.cs b/src/Microsoft.AspNetCore.OData/Routing/Conventions/AttributeRoutingConvention.cs index 4f4a992ae..0431b0297 100644 --- a/src/Microsoft.AspNetCore.OData/Routing/Conventions/AttributeRoutingConvention.cs +++ b/src/Microsoft.AspNetCore.OData/Routing/Conventions/AttributeRoutingConvention.cs @@ -172,7 +172,11 @@ private SelectorModel CreateActionSelectorModel(string prefix, IEdmModel model, ClearMetadata(newSelectorModel); // Add OData routing metadata - ODataRoutingMetadata odataMetadata = new ODataRoutingMetadata(prefix, model, pathTemplate); + ODataRoutingMetadata odataMetadata = new ODataRoutingMetadata(prefix, model, pathTemplate) + { + IsConventional = false + }; + newSelectorModel.EndpointMetadata.Add(odataMetadata); // replace the attribute routing template using absolute routing template to avoid appending any controller route template diff --git a/src/Microsoft.AspNetCore.OData/Routing/IODataRoutingMetadata.cs b/src/Microsoft.AspNetCore.OData/Routing/IODataRoutingMetadata.cs index 803b33f75..050bb2bfc 100644 --- a/src/Microsoft.AspNetCore.OData/Routing/IODataRoutingMetadata.cs +++ b/src/Microsoft.AspNetCore.OData/Routing/IODataRoutingMetadata.cs @@ -30,5 +30,10 @@ public interface IODataRoutingMetadata /// Gets the OData path template /// ODataPathTemplate Template { get; } + + /// + /// Gets the boolean value indicating whether it's from OData conventional routing, false means from attribute routing. + /// + bool IsConventional { get; } } } diff --git a/src/Microsoft.AspNetCore.OData/Routing/ODataRouteDebugMiddleware.cs b/src/Microsoft.AspNetCore.OData/Routing/ODataRouteDebugMiddleware.cs index 704383297..0f682514d 100644 --- a/src/Microsoft.AspNetCore.OData/Routing/ODataRouteDebugMiddleware.cs +++ b/src/Microsoft.AspNetCore.OData/Routing/ODataRouteDebugMiddleware.cs @@ -1,4 +1,4 @@ -//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- // // Copyright (c) .NET Foundation and Contributors. All rights reserved. // See License.txt in the project root for license information. @@ -107,6 +107,7 @@ internal static IList GetRouteInfo(HttpContext context) HttpMethods = endpoint.Metadata.GetMetadata()?.HttpMethods ?? EmptyHeaders, Pattern = routeEndpoint?.RoutePattern?.RawText ?? "N/A", IsODataRoute = metadata != null, + IsConventional = metadata != null ? metadata.IsConventional : false }; routInfoList.Add(info); @@ -183,6 +184,13 @@ private static void AppendRoute(StringBuilder builder, EndpointRouteInfo routeIn { builder.Append($"{routeInfo.Pattern}"); } + + if (routeInfo.IsODataRoute) + { + var isConventional = routeInfo.IsConventional ? "Yes" : "-"; + builder.Append($"{isConventional}"); + } + builder.AppendLine(""); } @@ -216,7 +224,8 @@ private static void AppendRoute(StringBuilder builder, EndpointRouteInfo routeIn Controller & Action HttpMethods - Template + Template + IsConventional ODATA_ROUTE_CONTENT @@ -244,6 +253,8 @@ internal class EndpointRouteInfo public string Pattern { get; set; } public bool IsODataRoute { get; set; } + + public bool IsConventional { get; set; } } } } diff --git a/src/Microsoft.AspNetCore.OData/Routing/ODataRoutingMetadata.cs b/src/Microsoft.AspNetCore.OData/Routing/ODataRoutingMetadata.cs index 47b33d8b7..bea577157 100644 --- a/src/Microsoft.AspNetCore.OData/Routing/ODataRoutingMetadata.cs +++ b/src/Microsoft.AspNetCore.OData/Routing/ODataRoutingMetadata.cs @@ -51,5 +51,10 @@ internal ODataRoutingMetadata() /// Gets the OData path template /// public ODataPathTemplate Template { get; } + + /// + /// Gets or sets a boolean value indicating from odata conventional routing. + /// + public bool IsConventional { get; set; } = true; } } diff --git a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net5.bsl b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net5.bsl index 33c7d45d6..e70b51040 100644 --- a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net5.bsl +++ b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net5.bsl @@ -1723,6 +1723,7 @@ public sealed class Microsoft.AspNetCore.OData.Results.SingleResult`1 : Microsof } public interface Microsoft.AspNetCore.OData.Routing.IODataRoutingMetadata { + bool IsConventional { public abstract get; } Microsoft.OData.Edm.IEdmModel Model { public abstract get; } string Prefix { public abstract get; } Microsoft.AspNetCore.OData.Routing.Template.ODataPathTemplate Template { public abstract get; } @@ -1849,6 +1850,7 @@ public class Microsoft.AspNetCore.OData.Routing.ODataRouteOptions { public sealed class Microsoft.AspNetCore.OData.Routing.ODataRoutingMetadata : IODataRoutingMetadata { public ODataRoutingMetadata (string prefix, Microsoft.OData.Edm.IEdmModel model, Microsoft.AspNetCore.OData.Routing.Template.ODataPathTemplate template) + bool IsConventional { public virtual get; public set; } Microsoft.OData.Edm.IEdmModel Model { public virtual get; } string Prefix { public virtual get; } Microsoft.AspNetCore.OData.Routing.Template.ODataPathTemplate Template { public virtual get; } diff --git a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net6.bsl b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net6.bsl index 33c7d45d6..e70b51040 100644 --- a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net6.bsl +++ b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net6.bsl @@ -1723,6 +1723,7 @@ public sealed class Microsoft.AspNetCore.OData.Results.SingleResult`1 : Microsof } public interface Microsoft.AspNetCore.OData.Routing.IODataRoutingMetadata { + bool IsConventional { public abstract get; } Microsoft.OData.Edm.IEdmModel Model { public abstract get; } string Prefix { public abstract get; } Microsoft.AspNetCore.OData.Routing.Template.ODataPathTemplate Template { public abstract get; } @@ -1849,6 +1850,7 @@ public class Microsoft.AspNetCore.OData.Routing.ODataRouteOptions { public sealed class Microsoft.AspNetCore.OData.Routing.ODataRoutingMetadata : IODataRoutingMetadata { public ODataRoutingMetadata (string prefix, Microsoft.OData.Edm.IEdmModel model, Microsoft.AspNetCore.OData.Routing.Template.ODataPathTemplate template) + bool IsConventional { public virtual get; public set; } Microsoft.OData.Edm.IEdmModel Model { public virtual get; } string Prefix { public virtual get; } Microsoft.AspNetCore.OData.Routing.Template.ODataPathTemplate Template { public virtual get; } diff --git a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.NetCore31.bsl b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.NetCore31.bsl index 33c7d45d6..e70b51040 100644 --- a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.NetCore31.bsl +++ b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.NetCore31.bsl @@ -1723,6 +1723,7 @@ public sealed class Microsoft.AspNetCore.OData.Results.SingleResult`1 : Microsof } public interface Microsoft.AspNetCore.OData.Routing.IODataRoutingMetadata { + bool IsConventional { public abstract get; } Microsoft.OData.Edm.IEdmModel Model { public abstract get; } string Prefix { public abstract get; } Microsoft.AspNetCore.OData.Routing.Template.ODataPathTemplate Template { public abstract get; } @@ -1849,6 +1850,7 @@ public class Microsoft.AspNetCore.OData.Routing.ODataRouteOptions { public sealed class Microsoft.AspNetCore.OData.Routing.ODataRoutingMetadata : IODataRoutingMetadata { public ODataRoutingMetadata (string prefix, Microsoft.OData.Edm.IEdmModel model, Microsoft.AspNetCore.OData.Routing.Template.ODataPathTemplate template) + bool IsConventional { public virtual get; public set; } Microsoft.OData.Edm.IEdmModel Model { public virtual get; } string Prefix { public virtual get; } Microsoft.AspNetCore.OData.Routing.Template.ODataPathTemplate Template { public virtual get; } From a59ad1163da35d218dc18a5231f44c3df7560370 Mon Sep 17 00:00:00 2001 From: Sam Xu Date: Thu, 11 Aug 2022 23:36:16 -0700 Subject: [PATCH 19/21] Add virtual method to extend the complex property serialization (#656) * Add virtual method to extend the complex property serialization * Update the public API test cases * Fix the typo --- .../Serialization/ODataResourceSerializer.cs | 87 +++++++++++++++---- .../Microsoft.AspNetCore.OData.xml | 51 +++++++---- .../PublicAPI.Unshipped.txt | 2 + .../ODataResourceSerializerTests.cs | 28 ++++++ ...rosoft.AspNetCore.OData.PublicApi.Net5.bsl | 2 + ...rosoft.AspNetCore.OData.PublicApi.Net6.bsl | 2 + ...t.AspNetCore.OData.PublicApi.NetCore31.bsl | 2 + 7 files changed, 140 insertions(+), 34 deletions(-) diff --git a/src/Microsoft.AspNetCore.OData/Formatter/Serialization/ODataResourceSerializer.cs b/src/Microsoft.AspNetCore.OData/Formatter/Serialization/ODataResourceSerializer.cs index 297e152e4..cd689a6eb 100644 --- a/src/Microsoft.AspNetCore.OData/Formatter/Serialization/ODataResourceSerializer.cs +++ b/src/Microsoft.AspNetCore.OData/Formatter/Serialization/ODataResourceSerializer.cs @@ -749,16 +749,16 @@ private async Task WriteDynamicComplexPropertiesAsync(ResourceContext resourceCo if (edmTypeReference.IsStructured() || (edmTypeReference.IsCollection() && edmTypeReference.AsCollection().ElementType().IsStructured())) { - ODataNestedResourceInfo nestedResourceInfo = new ODataNestedResourceInfo - { - IsCollection = edmTypeReference.IsCollection(), - Name = dynamicComplexProperty.Key, - }; + ODataNestedResourceInfo nestedResourceInfo + = CreateDynamicComplexNestedResourceInfo(dynamicComplexProperty.Key, dynamicComplexProperty.Value, edmTypeReference, resourceContext); - await writer.WriteStartAsync(nestedResourceInfo).ConfigureAwait(false); - await WriteDynamicComplexPropertyAsync(dynamicComplexProperty.Value, edmTypeReference, resourceContext, writer) - .ConfigureAwait(false); - await writer.WriteEndAsync().ConfigureAwait(false); + if (nestedResourceInfo != null) + { + await writer.WriteStartAsync(nestedResourceInfo).ConfigureAwait(false); + await WriteDynamicComplexPropertyAsync(dynamicComplexProperty.Value, edmTypeReference, resourceContext, writer) + .ConfigureAwait(false); + await writer.WriteEndAsync().ConfigureAwait(false); + } } } } @@ -834,16 +834,14 @@ private async Task WriteComplexPropertiesAsync(SelectExpandNode selectExpandNode { IEdmStructuralProperty complexProperty = selectedComplex.Key; - ODataNestedResourceInfo nestedResourceInfo = new ODataNestedResourceInfo + ODataNestedResourceInfo nestedResourceInfo = CreateComplexNestedResourceInfo(complexProperty, selectedComplex.Value, resourceContext); + if (nestedResourceInfo != null) { - IsCollection = complexProperty.Type.IsCollection(), - Name = complexProperty.Name - }; - - await writer.WriteStartAsync(nestedResourceInfo).ConfigureAwait(false); - await WriteComplexAndExpandedNavigationPropertyAsync(complexProperty, selectedComplex.Value, resourceContext, writer) - .ConfigureAwait(false); - await writer.WriteEndAsync().ConfigureAwait(false); + await writer.WriteStartAsync(nestedResourceInfo).ConfigureAwait(false); + await WriteComplexAndExpandedNavigationPropertyAsync(complexProperty, selectedComplex.Value, resourceContext, writer) + .ConfigureAwait(false); + await writer.WriteEndAsync().ConfigureAwait(false); + } } } @@ -960,6 +958,59 @@ private IEnumerable CreateNavigationLinks( } } + /// + /// Creates the to be written while writing this dynamic complex property. + /// + /// The dynamic property name. + /// The dynamic property value. + /// The edm type reference. + /// The context for the complex instance being written. + /// The nested resource info to be written. Returns 'null' will omit this serialization. + /// It enables customer to get more control by overriding this method. + public virtual ODataNestedResourceInfo CreateDynamicComplexNestedResourceInfo(string propertyName, object propertyValue, IEdmTypeReference edmType, ResourceContext resourceContext) + { + ODataNestedResourceInfo nestedInfo = null; + if (propertyName != null && edmType != null) + { + nestedInfo = new ODataNestedResourceInfo + { + IsCollection = edmType.IsCollection(), + Name = propertyName, + }; + } + + return nestedInfo; + } + + /// + /// Creates the to be written while writing this complex property. + /// + /// The complex property for which the nested resource info is being created. + /// The corresponding sub select item belongs to this complex property. + /// The context for the complex instance being written. + /// The nested resource info to be written. Returns 'null' will omit this complex serialization. + /// It enables customer to get more control by overriding this method. + public virtual ODataNestedResourceInfo CreateComplexNestedResourceInfo(IEdmStructuralProperty complexProperty, PathSelectItem pathSelectItem, ResourceContext resourceContext) + { + if (complexProperty == null) + { + throw Error.ArgumentNull(nameof(complexProperty)); + } + + ODataNestedResourceInfo nestedInfo = null; + + if (complexProperty.Type != null) + { + nestedInfo = new ODataNestedResourceInfo + { + IsCollection = complexProperty.Type.IsCollection(), + Name = complexProperty.Name + }; + } + + return nestedInfo; + } + /// /// Creates the to be written while writing this entity. /// diff --git a/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml b/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml index dc0971029..20212a41a 100644 --- a/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml +++ b/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml @@ -1094,6 +1094,20 @@ The type to test. True if the type is a DateTime; false otherwise. + + + Determine if a type is a . + + The type to test. + True if the type is a DateOnly; false otherwise. + + + + Determine if a type is a . + + The type to test. + True if the type is a TimeOnly; false otherwise. + Determine if a type is a TimeSpan. @@ -4606,6 +4620,27 @@ Write the navigation link for the select navigation properties. + + + Creates the to be written while writing this dynamic complex property. + + The dynamic property name. + The dynamic property value. + The edm type reference. + The context for the complex instance being written. + The nested resource info to be written. Returns 'null' will omit this serialization. + It enables customer to get more controll by overriding this method. + + + + Creates the to be written while writing this complex property. + + The complex property for which the nested resource info is being created. + The corresponding sub select item belongs to this complex property. + The context for the complex instance being written. + The nested resource info to be written. Returns 'null' will omit this complex serialization. + It enables customer to get more controll by overriding this method. + Creates the to be written while writing this entity. @@ -14382,19 +14417,3 @@ -ummary> - The value segment. - - - - Gets the value segment. - - - - - - - - - - diff --git a/src/Microsoft.AspNetCore.OData/PublicAPI.Unshipped.txt b/src/Microsoft.AspNetCore.OData/PublicAPI.Unshipped.txt index 3ee9900ec..30f0038b1 100644 --- a/src/Microsoft.AspNetCore.OData/PublicAPI.Unshipped.txt +++ b/src/Microsoft.AspNetCore.OData/PublicAPI.Unshipped.txt @@ -1736,7 +1736,9 @@ virtual Microsoft.AspNetCore.OData.Formatter.Serialization.ODataEdmTypeSerialize virtual Microsoft.AspNetCore.OData.Formatter.Serialization.ODataEnumSerializer.CreateODataEnumValue(object graph, Microsoft.OData.Edm.IEdmEnumTypeReference enumType, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) -> Microsoft.OData.ODataEnumValue virtual Microsoft.AspNetCore.OData.Formatter.Serialization.ODataPrimitiveSerializer.CreateODataPrimitiveValue(object graph, Microsoft.OData.Edm.IEdmPrimitiveTypeReference primitiveType, Microsoft.AspNetCore.OData.Formatter.Serialization.ODataSerializerContext writeContext) -> Microsoft.OData.ODataPrimitiveValue virtual Microsoft.AspNetCore.OData.Formatter.Serialization.ODataResourceSerializer.AppendDynamicProperties(Microsoft.OData.ODataResource resource, Microsoft.AspNetCore.OData.Formatter.Serialization.SelectExpandNode selectExpandNode, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) -> void +virtual Microsoft.AspNetCore.OData.Formatter.Serialization.ODataResourceSerializer.CreateComplexNestedResourceInfo(Microsoft.OData.Edm.IEdmStructuralProperty complexProperty, Microsoft.OData.UriParser.PathSelectItem pathSelectItem, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) -> Microsoft.OData.ODataNestedResourceInfo virtual Microsoft.AspNetCore.OData.Formatter.Serialization.ODataResourceSerializer.CreateComputedProperty(string propertyName, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) -> Microsoft.OData.ODataProperty +virtual Microsoft.AspNetCore.OData.Formatter.Serialization.ODataResourceSerializer.CreateDynamicComplexNestedResourceInfo(string propertyName, object propertyValue, Microsoft.OData.Edm.IEdmTypeReference edmType, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) -> Microsoft.OData.ODataNestedResourceInfo virtual Microsoft.AspNetCore.OData.Formatter.Serialization.ODataResourceSerializer.CreateETag(Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) -> string virtual Microsoft.AspNetCore.OData.Formatter.Serialization.ODataResourceSerializer.CreateNavigationLink(Microsoft.OData.Edm.IEdmNavigationProperty navigationProperty, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) -> Microsoft.OData.ODataNestedResourceInfo virtual Microsoft.AspNetCore.OData.Formatter.Serialization.ODataResourceSerializer.CreateODataAction(Microsoft.OData.Edm.IEdmAction action, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) -> Microsoft.OData.ODataAction diff --git a/test/Microsoft.AspNetCore.OData.Tests/Formatter/Serialization/ODataResourceSerializerTests.cs b/test/Microsoft.AspNetCore.OData.Tests/Formatter/Serialization/ODataResourceSerializerTests.cs index 8e726548d..ba98c0d98 100644 --- a/test/Microsoft.AspNetCore.OData.Tests/Formatter/Serialization/ODataResourceSerializerTests.cs +++ b/test/Microsoft.AspNetCore.OData.Tests/Formatter/Serialization/ODataResourceSerializerTests.cs @@ -234,6 +234,34 @@ public async Task WriteObjectInlineAsync_WritesODataResourceFrom_CreateResource( writer.Verify(); } + [Fact] + public async Task WriteObjectInlineAsync_Calls_CreateComplexNestedResourceInfo_ForEachSelectedComplexProperty() + { + // Arrange + SelectExpandNode selectExpandNode = new SelectExpandNode + { + SelectedComplexProperties = new Dictionary + { + { new Mock().Object, null }, + { new Mock().Object, null } + } + }; + + Mock writer = new Mock(); + Mock serializer = new Mock(_serializerProvider); + serializer.Setup(s => s.CreateSelectExpandNode(It.IsAny())).Returns(selectExpandNode); + serializer.CallBase = true; + + serializer.Setup(s => s.CreateComplexNestedResourceInfo(selectExpandNode.SelectedComplexProperties.ElementAt(0).Key, null, It.IsAny())).Verifiable(); + serializer.Setup(s => s.CreateComplexNestedResourceInfo(selectExpandNode.SelectedComplexProperties.ElementAt(1).Key, null, It.IsAny())).Verifiable(); + + // Act + await serializer.Object.WriteObjectInlineAsync(_customer, _customerType, writer.Object, _writeContext); + + // Assert + serializer.Verify(); + } + [Fact] public async Task WriteObjectInlineAsync_Calls_CreateNavigationLink_ForEachSelectedNavigationProperty() { diff --git a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net5.bsl b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net5.bsl index e70b51040..a8e204cae 100644 --- a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net5.bsl +++ b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net5.bsl @@ -2216,7 +2216,9 @@ public class Microsoft.AspNetCore.OData.Formatter.Serialization.ODataResourceSer public ODataResourceSerializer (Microsoft.AspNetCore.OData.Formatter.Serialization.IODataSerializerProvider serializerProvider) public virtual void AppendDynamicProperties (Microsoft.OData.ODataResource resource, Microsoft.AspNetCore.OData.Formatter.Serialization.SelectExpandNode selectExpandNode, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) + public virtual Microsoft.OData.ODataNestedResourceInfo CreateComplexNestedResourceInfo (Microsoft.OData.Edm.IEdmStructuralProperty complexProperty, Microsoft.OData.UriParser.PathSelectItem pathSelectItem, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) public virtual Microsoft.OData.ODataProperty CreateComputedProperty (string propertyName, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) + public virtual Microsoft.OData.ODataNestedResourceInfo CreateDynamicComplexNestedResourceInfo (string propertyName, object propertyValue, Microsoft.OData.Edm.IEdmTypeReference edmType, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) public virtual string CreateETag (Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) public virtual Microsoft.OData.ODataNestedResourceInfo CreateNavigationLink (Microsoft.OData.Edm.IEdmNavigationProperty navigationProperty, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) public virtual Microsoft.OData.ODataAction CreateODataAction (Microsoft.OData.Edm.IEdmAction action, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) diff --git a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net6.bsl b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net6.bsl index e70b51040..a8e204cae 100644 --- a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net6.bsl +++ b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net6.bsl @@ -2216,7 +2216,9 @@ public class Microsoft.AspNetCore.OData.Formatter.Serialization.ODataResourceSer public ODataResourceSerializer (Microsoft.AspNetCore.OData.Formatter.Serialization.IODataSerializerProvider serializerProvider) public virtual void AppendDynamicProperties (Microsoft.OData.ODataResource resource, Microsoft.AspNetCore.OData.Formatter.Serialization.SelectExpandNode selectExpandNode, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) + public virtual Microsoft.OData.ODataNestedResourceInfo CreateComplexNestedResourceInfo (Microsoft.OData.Edm.IEdmStructuralProperty complexProperty, Microsoft.OData.UriParser.PathSelectItem pathSelectItem, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) public virtual Microsoft.OData.ODataProperty CreateComputedProperty (string propertyName, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) + public virtual Microsoft.OData.ODataNestedResourceInfo CreateDynamicComplexNestedResourceInfo (string propertyName, object propertyValue, Microsoft.OData.Edm.IEdmTypeReference edmType, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) public virtual string CreateETag (Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) public virtual Microsoft.OData.ODataNestedResourceInfo CreateNavigationLink (Microsoft.OData.Edm.IEdmNavigationProperty navigationProperty, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) public virtual Microsoft.OData.ODataAction CreateODataAction (Microsoft.OData.Edm.IEdmAction action, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) diff --git a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.NetCore31.bsl b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.NetCore31.bsl index e70b51040..a8e204cae 100644 --- a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.NetCore31.bsl +++ b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.NetCore31.bsl @@ -2216,7 +2216,9 @@ public class Microsoft.AspNetCore.OData.Formatter.Serialization.ODataResourceSer public ODataResourceSerializer (Microsoft.AspNetCore.OData.Formatter.Serialization.IODataSerializerProvider serializerProvider) public virtual void AppendDynamicProperties (Microsoft.OData.ODataResource resource, Microsoft.AspNetCore.OData.Formatter.Serialization.SelectExpandNode selectExpandNode, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) + public virtual Microsoft.OData.ODataNestedResourceInfo CreateComplexNestedResourceInfo (Microsoft.OData.Edm.IEdmStructuralProperty complexProperty, Microsoft.OData.UriParser.PathSelectItem pathSelectItem, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) public virtual Microsoft.OData.ODataProperty CreateComputedProperty (string propertyName, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) + public virtual Microsoft.OData.ODataNestedResourceInfo CreateDynamicComplexNestedResourceInfo (string propertyName, object propertyValue, Microsoft.OData.Edm.IEdmTypeReference edmType, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) public virtual string CreateETag (Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) public virtual Microsoft.OData.ODataNestedResourceInfo CreateNavigationLink (Microsoft.OData.Edm.IEdmNavigationProperty navigationProperty, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) public virtual Microsoft.OData.ODataAction CreateODataAction (Microsoft.OData.Edm.IEdmAction action, Microsoft.AspNetCore.OData.Formatter.ResourceContext resourceContext) From 07adec46ad4dbbdeed81a0ea7272246a4bd762f6 Mon Sep 17 00:00:00 2001 From: Dean-ZhenYao-Wang <137473325@qq.com> Date: Sat, 13 Aug 2022 00:46:50 +0800 Subject: [PATCH 20/21] Fixed an issue where attributes of the same name cannot be expanded when subclasses inherit and hide attributes of the parent class (#645) * Fixed an issue where attributes of the same name cannot be expanded when subclasses inherit and hide attributes of the parent class * This code fixes an issue where 'History of code' was unable to obtain attributes with the same name as the parent class after the subclass hid the parent class member. --- .../Query/Expressions/SelectExpandBinder.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.OData/Query/Expressions/SelectExpandBinder.cs b/src/Microsoft.AspNetCore.OData/Query/Expressions/SelectExpandBinder.cs index 3372fae8d..50bd6fb88 100644 --- a/src/Microsoft.AspNetCore.OData/Query/Expressions/SelectExpandBinder.cs +++ b/src/Microsoft.AspNetCore.OData/Query/Expressions/SelectExpandBinder.cs @@ -231,7 +231,22 @@ public virtual Expression CreatePropertyValueExpression(QueryBinderContext conte PropertyInfo propertyInfo = source.Type.GetProperty(propertyName, BindingFlags.DeclaredOnly); if (propertyInfo == null) { - propertyInfo = source.Type.GetProperty(propertyName); + /* + History of code: + propertyInfo = source.Type.GetProperty(propertyName); + This code fixes an issue where 'History of code' was unable to obtain attributes with the same name as the parent class after the subclass hid the parent class member. + Such as: + 'History of code' cannot get the Key property of the Child. + public class Father + { + public string Key { get; set; } + } + public class Child : Father + { + public new Guid Key { get; set; } + } + */ + propertyInfo = source.Type.GetProperties().Where(m => m.Name.Equals(propertyName)).FirstOrDefault(); } Expression propertyValue = Expression.Property(source, propertyInfo); From 9e91f057c427bb9ba95f127f4b04402e6527711c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Habinshuti?= Date: Mon, 15 Aug 2022 16:47:28 +0300 Subject: [PATCH 21/21] Update release version to 8.0.11 and referenced ODL to 7.12.2 (#665) * Update release version to 8.0.11 and referenced ODL to 7.12.2 * Update ODL dependency range --- .../Microsoft.AspNetCore.OData.csproj | 6 +++--- tool/builder.versions.settings.targets | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.csproj b/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.csproj index 58885a451..006f98d86 100644 --- a/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.csproj +++ b/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.csproj @@ -33,13 +33,13 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/tool/builder.versions.settings.targets b/tool/builder.versions.settings.targets index c89f49cb0..f88c5ffdb 100644 --- a/tool/builder.versions.settings.targets +++ b/tool/builder.versions.settings.targets @@ -3,13 +3,13 @@ 8 0 - 10 + 11 - [7.9.4, 8.0.0) + [7.12.2, 8.0.0) [1.0.8, 2.0.0)