OData / AspNetCoreOData

ASP.NET Core OData: A server library built upon ODataLib and ASP.NET Core
Other
457 stars 158 forks source link

How to Configure a Default PageSize? #243

Open donile opened 3 years ago

donile commented 3 years ago

Is it possible to set a default PageSize when configuring the OData services using the the IMvcBuilder.AddOData() extension method?

If not, is there a suggested best practice for setting the default PageSize? We would like to avoid having to specify the default PageSize on each [EnableQuery] we use.

Example

...
services
    .AddControllers()
    .AddOData(options => {
        ...
        options.QuerySettings.PageSize = Configuration["OData:PageSize"];
        ...
     });
...
jbaehr commented 3 years ago

While in v7.5 I could do something like this in Startup.ConfigureServices(IServiceCollection services) (ODataConfig being a custom type of mine):

            var odataConfig = this.Configuration.GetSection(ODataConfig.DefaultKey).Get<ODataConfig>();
            services.AddODataQueryFilter(new EnableQueryAttribute()
            {
                PageSize = odataConfig.PageSize,
                HandleNullPropagation = HandleNullPropagationOption.False, // cf. https://jira.mongodb.org/browse/CSHARP-1771
            });

However, in v8.0 there is no AddODataQueryFilter extension any more. Is there a known alternative?

jbaehr commented 3 years ago

@xuzhg Are there any plans for bringing this feature back to the v8.x line? Personally, I consider this as a regression, not an enhancement, as it used to work with v7.5 Or is there an alternative to the AddODataQueryFilter API that allows runtime configuration of the default page size?

xuzhg commented 3 years ago

added at a3cba39588f952377d2aace17bca89cd3c0a39df. Will ship with 8.0.4 soon.

Before that, would you please help test it using the nightly package and let me know any problem?

jbaehr commented 3 years ago

added at a3cba39. Will ship with 8.0.4 soon.

That was quick, thanks a lot!

Before that, would you please help test it using the nightly package and let me know any problem?

I'll take a look on Monday.

jbaehr commented 3 years ago

@xuzhg Can you tell me how to access the nightly package? The link from the Readme.md points to an access-restricted azure pipeline, which my visual studio account is not allowed to see (after successful login I get this: "401 - Uh-oh, you do not have access.").

sorry. Found it: https://www.myget.org/feed/webapinetcore/package/nuget/Microsoft.AspNetCore.OData

jbaehr commented 3 years ago

Works like a charm. I'm looking forward to the official 8.0.4.

(Note that I had to remove the explicit [EnableQuery(PageSize=...]) attributes on my controllers that inherit ODataController. I don't remember whether that was required on v7.5, but did reintroduce those attributes only for v8.0. So the diff of my code between using v7.5 and v8.0 became even smaller with 8.0.4-Nightly202111081315.)

Thanks a lot!

PieterBoeren commented 3 years ago

I have trouble to get this to work, can an example be updated to use this new approach?

I added the extension method, but it's unclear to me what I then have to remove in my controllers/AddOData extension method (as @jbaehr mentioned above, something has to be removed):

services.AddODataQueryFilter(new EnableQueryAttribute() { PageSize = 10 });

(I'm using the released 8.0.4)

FrancisHoran commented 1 month ago

If someone like me wants to setup a page limit in just one place, without overriding of [EnableQuery], use this method for your Edm Model -

    const int PageSize = 100;
    private static ODataConventionModelBuilder UsePaging(this ODataConventionModelBuilder modelBuilder)
    {
        foreach (var entitySet in modelBuilder.EntitySets)
        {
            var queryConfiguration = entitySet.EntityType.QueryConfiguration;
            queryConfiguration.SetPageSize(PageSize);
        }

        return modelBuilder;
    }

It will work for all of yours entity sets even if they are results of function.

In case you wanna to do the same for complex types too, use

    private static ODataConventionModelBuilder UseComplexTypesPaging(this ODataConventionModelBuilder modelBuilder)
    {
        foreach (var structuralType in modelBuilder.StructuralTypes)
        {
            var queryConfiguration = structuralType.QueryConfiguration;
            queryConfiguration.SetPageSize(PageSize);
        }

        return modelBuilder;
    }
rpallares commented 1 month ago

If someone like me wants to setup a page limit in just one place, without overriding of [EnableQuery], use this method for your Edm Model -

    const int PageSize = 100;
    private static ODataConventionModelBuilder UsePaging(this ODataConventionModelBuilder modelBuilder)
    {
        foreach (var entitySet in modelBuilder.EntitySets)
        {
            var queryConfiguration = entitySet.EntityType.QueryConfiguration;
            queryConfiguration.SetPageSize(PageSize);
        }

        return modelBuilder;
    }

It will work for all of yours entity sets even if they are results of function.

In case you wanna to do the same for complex types too, use

    private static ODataConventionModelBuilder UseComplexTypesPaging(this ODataConventionModelBuilder modelBuilder)
    {
        foreach (var structuralType in modelBuilder.StructuralTypes)
        {
            var queryConfiguration = structuralType.QueryConfiguration;
            queryConfiguration.SetPageSize(PageSize);
        }

        return modelBuilder;
    }

That's a nice way to do it using some option. Unfortunatly I dont use server side paging anymore as it destroy performances. Here is a post that explain why and how: https://github.com/OData/AspNetCoreOData/pull/1271#issuecomment-2209499421