OData / WebApi

OData Web API: A server library built upon ODataLib and WebApi
https://docs.microsoft.com/odata
Other
855 stars 475 forks source link

Provide Query support like .NET Framework version of OData #1522

Open InariTheFox opened 6 years ago

InariTheFox commented 6 years ago

The older OData (v4) functionality allowed for the use of the OData Query extensions on Web API projects without the full use of OData. This was exceptionally handy for creating much simpler OData-like REST endpoints, or essentially a mixed environment, where OData and Web API could co-exist in the same controller if needed. I realize this is not exactly the expected use case, but this functionality greatly simplifies smaller development and also helps to give REST endpoints much more flexibility without the need to build up and configure a complex (and often clunky IMHO) OData model. If we could get the same level of functionality for .NET Core 2.x that would be amazing.

freeranger commented 6 years ago

@InariTheFox could you provide a bit more detail on what you are trying to do? Your description sounds like exactly what we do with OData now in Asp.NetCore

We accept OData queries via an ODataQueryOptions parameter to a controller action and then apply that to an iQueryable We don’t use EDMs or any of that and our controllers are just normal ones, not based on ODataController

If this is the sort of thing you are trying to do then I can telling it how to configure it

InariTheFox commented 6 years ago

@freeranger The older .NET framework version would hook in to the controller pipeline and apply the ODataQueryOptions directly on the result of the method automatically, without the need for all the boilerplate code that would be necessary. Now obviously the flexibility of .NET Core is meant to be just that a "core" implementation, but I am wondering if there's a way to inject the same functionality in to the request lifecycle the same way that it is done now for the .NET framework version?

freeranger commented 6 years ago

Hi,

Not sure what you mean about "all" the boilerplate. We did little more than:

            return app.UseMvc(routebuilder =>
            {
                routebuilder.EnableDependencyInjection(builder =>
                {
                    builder.AddService(Microsoft.OData.ServiceLifetime.Singleton, typeof(ODataUriResolver), typeof(CaseInsensitiveResolver));
                });
                routebuilder.Filter().OrderBy().Select().MaxTop(int.MaxValue);
            });

and then our controller acitons accept an ODataQurtyOptions<T> options and then options.ApplyTo(<some IQueryable<T>)

InariTheFox commented 6 years ago

@freeranger Previous incarnations of OData would automatically bind to the ODataQueryOptions during the appropriate time, and also call options.ApplyTo() once the request was being finalized to send to the client, without having to code this. I guess for the time being I could create the appropriate blocks of code and plug them in to the ActionFilters or wherever they may go. It still would be nice if this was included in a future version (as I believe my code would be far from perfect.)

nhat-tong commented 6 years ago

@InariTheFox: you can do the same thing in .Net Core as .Net Framework with the lastest version of Microsoft.AspnetCore.Odata (v7.0.0). It would automatically bind to the ODataQueryOptions and also call options.ApplyTo() for you. Firstly, you need enable ODataQueryOptions in Startup file like @freeranger mentioned. Then, you can place the attribute [EnableQuery] on the methods you want et that's all.

JohnGalt1717 commented 6 years ago

The problem is that $count=true doesn't work resulting in the output staying the same base json [] instead of {Results: [], InlineCount: xxx}

So it's impossible to do pagination.

And if you create your own jsonoutputformatter to format it, the issue is that there doesn't appear to be a way to get at the count in the WriteResponseBodyAsync to write the property.