AspNetCoreOData icon indicating copy to clipboard operation
AspNetCoreOData copied to clipboard

How to Configure a Default PageSize?

Open donile opened this issue 4 years ago • 9 comments

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"];
        ...
     });
...

donile avatar Jul 20 '21 20:07 donile

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 avatar Sep 29 '21 15:09 jbaehr

@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?

jbaehr avatar Nov 05 '21 16:11 jbaehr

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?

xuzhg avatar Nov 05 '21 17:11 xuzhg

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 avatar Nov 05 '21 20:11 jbaehr

~~@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 avatar Nov 08 '21 14:11 jbaehr

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!

jbaehr avatar Nov 08 '21 15:11 jbaehr

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)

PieterBoeren avatar Nov 10 '21 10:11 PieterBoeren

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;
    }

FrancisHoran avatar Oct 03 '24 15:10 FrancisHoran

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

rpallares avatar Oct 03 '24 17:10 rpallares