Skip to content

Feature/ Make SelectExpandBinder and AggregationBinder public and let override there methods#1921

Open
savelievser wants to merge 328 commits into
OData:masterfrom
savelievser:feature/make-binders-public
Open

Feature/ Make SelectExpandBinder and AggregationBinder public and let override there methods#1921
savelievser wants to merge 328 commits into
OData:masterfrom
savelievser:feature/make-binders-public

Conversation

@savelievser

@savelievser savelievser commented Oct 3, 2019

Copy link
Copy Markdown

Issues

This pull request fixes issue implements feature #1900 .

Description

SelectExpandBinder and AggregationBinder were made public and some of there methods were made protected virtual to let developers override it's functionality (like in FilterBinder). Creation of these classes were moved to new DataBinderProvider class, because approach with registering them with IServiceProvider will require big refactoring.

Checklist (Uncheck if it is not completed)

  • Build and test with one-click build and test script passed

Additional work necessary

I think no

robward-ms and others added 30 commits December 4, 2017 14:27
… by some class constructors.

Allow action selector to pick a default method if none have matched.
Fix StackOverflow in ArgumentNullException()
Minor code cleanup.
…taOptions.

Inject settings and options into both the global and pre-request containers.
Add Fluent APIs to IRouteBuilder to configure settings and options.
Add EnableContinueOnErrorHeader for batching.
Implement NonValidatingParameterBindingAttribute.
Implement ODataNullValueMessageHandler as a IResultFilter.
Implement ODataQueryParameterBindingAttribute.
Fixed $count calculation in ODataFeature.TotalCount.
Fixed an ETag is where the etag handler was not being retrieved from the per-route service container.
Refactor EnableQueryAttribute to move model retrieval to ActionDescriptorExtensions.
Added extension methods to get and set a default time zone
Convert UnitTest projects to NetFx 4.5.2
Enable Xunit Analyzers & fix reported issues, including:
 - Assert.Equal(0, collection.Count) => Assert.Empty(collection)
 - Assert.Equal(1, collection.Count) => Assert.Single(collection)
 - Assert.Equal(var, const) => Assert.Equal(const, var)
 - Assert.True(collection.Contains(find)) => Assert.Contains(find, collection)
 - Remove duplicate Theory test cases
 - Cleanup unused Theory param warnings
 - Remove Assert.NotNull() on structs
Avoid .Wait() and .Results() in favor of async Task return for async unit tests
Cleanup unused test code.
Make OData formatters ignore non-OData requests
Implement MediaMapping for AspNetCore
Refactor MediaMappings
Move DefaultODataETagHandler to shared code
Set InternalUrlHelper in ODataDeserializerContext
Skip OData output formatting for non-OData routes.
Improved routing action selection.
Add EnableDependencyInjection() for non-OData routes.
Bind HttpRequest(Message) into per-request OData container
between IODataFeature in AspNetCore.OData and HttpRequestMessageProperties
in AspNet.OData.
merge master (WebApi 6.2) into feature/netcore
In the AspNetCore version of WebApi, the ODataActionSelector is used for
all routes. If it is non-OData route, the route is handled by the default
IActionSelector.

However, a check was being made to see if the routing conventions are available,
which requires a route name to obtain the conventions from the request container.
This check failed due to a missing route name.

This fix delays the check for routing conventions until after the request has been
verified to match and OData route by checking for an ODataPath. If the conventions are
not available, the route is handled by the default IActionSelector.
Convert E2E projects to NetFx 4.5.2
Consolidate E2E projects into a single project
Enable Xunit Analyzers & fix reported issues, including:
 - Assert.Equal(0, collection.Count) => Assert.Empty(collection)
 - Assert.Equal(1, collection.Count) => Assert.Single(collection)
 - Assert.Equal(var, const) => Assert.Equal(const, var)
 - Assert.True(collection.Contains(find)) => Assert.Contains(find, collection)
 - Remove duplicate Theory test cases
 - Cleanup unused Theory param warnings
 - Remove Assert.NotNull() on structs
Avoid .Wait() and .Results() in favor of async Task return for async unit tests
Cleanup unused test code.

Most of the files in test/E2ETest/Microsoft.Test.E2E.AspNet.OData are existing files moved
into this new folder. However, the files have some churn, i.e. namespaces, using, and some
more than others, including the changes described above.

Since there is no first-class rename operation in git, some of the moves + edits are showing up
as add/delete pairs instead of rename + edit.

The following files were moved with very little code churn:
test/E2ETest/Common -> test/E2ETest/Microsoft.Test.E2E.AspNet.OData/Common
test/E2ETest/WebStack.QA.Common.Tests -> test/E2ETest/Microsoft.Test.E2E.AspNet.OData/Common
test/E2ETest/WebStack.QA.Share -> test/E2ETest/Microsoft.Test.E2E.AspNet.OData/Common
test/E2ETest/WebStack.QA.Instancing -> test/E2ETest/Microsoft.Test.E2E.AspNet.OData/Common

The following files were moved with moderate code churn:
test/E2ETest/WebStack.QA.Test.OData -> test/E2ETest/Microsoft.Test.E2E.AspNet.OData

The following files were mostly deleted and replaced with simplified versions using
existing code:
test/E2ETest/Nuwa -> test/E2ETest/Microsoft.Test.E2E.AspNet.OData/Common/Execution
test/E2ETest/Nuwa.WebStack -> test/E2ETest/Microsoft.Test.E2E.AspNet.OData/Common/Execution

Specifically, convert from Xunit 1.9 to 2.x required modifying the Xunit approach from a
custom test case to a test fixture. The test/E2ETest/Microsoft.Test.E2E.AspNet.OData/Common/Execution
folder contains the classes from Nuwa the implement the in-proc web server and hook it into
Xunit to start/stop the service for each test class.

One of the reasons for the project coalescing and simplification is that this test framework needs
to run on both .NET Framework and .NET Core. By reducing to a single project and eliminating
complexity in the test framework, the porting costs to .NET Core are reduced.
…iner.

This change allows FilterQueryOption to execute without setting a
RequestContainer on ODataQueryContext, which is an internal property
set by ODataQueryOptions from the requests' container.

In this stand-alone scenario, a container cannot be injected so the uses
of the container now have a fallback option for creating objects when the
container does not exist.

However, one of those objects was an internal assembly resolver. On
.NET, the default assembly resolver can be used. However, .NET Core
does not implementation a default assembly resolver. .NET Core 2.x
implments the AppDomain class to it can be used to get all assemblies
in the domain.  This addition fixes a known issue where a NotImplemented()
exception was thrown when no part manager was found to fulfill the request
for assemblies.
Made per-route services container public since developers may want
to gain access to the container in their own code. This also exposes
two methods for creating OData service containers for using dependency
injection in stand-alone (non-ASP.NET) scenarios.
and the Result object is it is a StatusCodeResult.
…Data#1242)

* ODataSerializerProviderProxy is used to delay-load the ODataSerializerProvider from the
service container container. The proxy is used by the formatter, which is created outside
of the service container and therefore can't use the container directly. At run-time, the
services container from the active request is saved on a property on the proxy before the
formatter asks for the ODataSerializerProvider; once it does ask, the proxy loads the
ODataSerializerProvider from container. In most cases, all works great and as expected.

Formatters are a bit odd in that they are not per-route; they are injected into the configuration
via a controller configuration attribute or AddOdata() service container extension.  However,
the library "supports" injection of the ODataSerializerProvider on a per-route basis, i.e. you
can do it. ODataSerializerProvider on a per-route basis because there are only one set of formatters
on the config/global service container. As to which ODataSerializerProvider is used, it's a race
condition as to which route gets a request and sets the services container for the proxy.

This change eliminates ODataSerializerProviderProxy in favor of retrieving the
ODataSerializerProvider in runtime from the service container. This allows suporting
ODataSerializerProvider's on a per-route basis. A side effect of this is that if causes a
change the API of the formatter to not expose the ODataSerializerProvider as a public property.

Note: everything in the mail equally applies to AspNetCore as well as ODataDeserializerProviderProxy, etc...
…sses of

NavigationSourceRoutingConvention to override SelectAction without access
to internal classes.
…API baseline for AspNet.

This is being done before the checkin for AspNetCore tests to allow for easy viewing/diffing
between AspNet and AspNetCore public APIs.
an instance to be constructed using only an ApplicationPartManager and
enabled the default constructor to be used as well, which will reason
over all assemblies in the AppDomain.

While the ApplicationPartManager is an ASP.NET Core class, it is simple
to create and populate with one or more selected assemblies, allowing
for easy use of ODataConventionModelBuilder in scoped & stand-alone scenarios:

  var partManager = new ApplicationPartManager();
  var part = new AssemblyPart(typeof(<class>).Assembly);
  partManager.ApplicationParts.Add(part);

  var builder = new ODataConventionModelBuilder(partManager);
Batching is configured the same as it is in the ASP.NET version with
the exception of the batching middleware which is configured using the
following extensions from the Microsoft.AspNet.OData.Extensions namespace
in the StartUp.Configure() method using the IApplicationBuilder object:

  applicationBuilder.UseODataBatching()

Each OData route may have its own batching handler which can be passed into
a call to MapODataServiceRoute(), in the StartUp.Configure() method using
the IApplicationBuilder object:

  app.UseMvc(routes =>
  {
      routes.MapODataServiceRoute("OData", "odata", edmModel, new DefaultODataBatchHandler());
  });

Since the APIs for batching use ASP.NET constructs directly, there is very little
shared code in the batching feature. The batching APIs use the same design patterns
but different in the ASP.NET objects the reference, e.g. HttpRequestMessage vs HttpRequest.
KanishManuja-MS and others added 19 commits July 31, 2019 18:20
* Update minimum version of ODL to be 7.6

* Add release note links to nuget.org
When WebAPI executed `$expand` and `$select` it takes SelectExpandClause and transforms it to apply all selects, level and expand filters. For example
it you have `WorkItems?$expand=Children` it will be automatically (in same cases) converted into
`WorkItems?$select=<list of all columns>&$expand=Children($select=<list of all columns>)`.
It's implemented as creating new SelectExpandClause, however other options inside `$expand` were ignored as a result `WorkItems?$expand=Children($filter=State eq 'Active')` was translated to `WorkItems?$select=<list of all columns>&$expand=Children($select=<list of all columns>)`

Fixing that issue
* create skip token using edm rather than clr property name, and clarify variable names

* add end-to-end tests to ensure generated skip tokens match the camel-cased edm property name
…tions

Ensure that all expand item options preserved when translating SELECT *
* Enable expand on navigation properties on complex types

* Fix PR issues; Do not introduce any public elements

* fix build issues

* Update Microsoft.Test.E2E.AspNetCore.OData.csproj

* Add test case for open type

* Update SelectExpandNode.cs

* Update SelectExpandNode.cs
* Update to OData Library v 7.6.1, fix the failing test cases

* Change the Package dependency to 7.6.0 to 7.6.1
@savelievser

Copy link
Copy Markdown
Author

How can I setup local environment to receive same errors as continuous-integration/vsts?
Locally run build.cmd executes successfully. Can somebody tell what errors are?

@KanishManuja-MS

Copy link
Copy Markdown
Contributor

How can I setup local environment to receive same errors as continuous-integration/vsts?
Locally run build.cmd executes successfully. Can somebody tell what errors are?

I know it is slow and painful but we will soon fix this issue which will enable you to see the build results. In the meanwhile, here is the output -

image

@savelievser

savelievser commented Oct 7, 2019

Copy link
Copy Markdown
Author

Thank you @KanishManuja-MS . Do I need to perform any actions to let your team start review process of this PR?

@savelievser

Copy link
Copy Markdown
Author

Hi @KanishManuja-MS!
Could you please provide some estimation of how long will it take to review this PR? In our project we are counting on this change and it would be great to understand in what library version it can be potentially included. Thanks!

@bcorkovic

Copy link
Copy Markdown

Hi @KanishManuja-MS

We are also interested into this PR. Is there any timeframe or option to help?

@dropsonic

Copy link
Copy Markdown

Any updates on this PR? It's been a year.

@xuzhg xuzhg force-pushed the master branch 2 times, most recently from 4c43a84 to ddfd3dd Compare May 29, 2026 01:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.