Setting OData result Page Size at runtime in WebAPI app

时间:2016-08-31 12:16:48

标签: asp.net asp.net-web-api2 odata

I am writing an ASP.NET Web API 2 web service using OdataControllers I have found out how to set page size using the PageSize Property of the EnableQueryAttribute. I want to allow the users of my web service to set the page size in the app.config and then have the application read this setting and set the page size. The problem is that using the attribute requires Page Size be set to a compile time constant.

Usage of attribute:

[EnableQuery(PageSize = 10)]
public IHttpActionResult GetProducts()
{
    return repo.GetProducts();
}

One proposed solution I have seen is to construct the EnableQueryAttribute and set it on the HTTPConfiguration config object like this

int customSize = ReadPageSizeSettingFromConfigFile();

var attr = new EnableQueryAttribute { PageSize = customSize };
config.AddODataQueryFilter(attr);

but this doesn't actually work. The HttpConfiguration's Filter collection remains empty.

config object watch view

A comment on another post (buried in a list of comments) suggested removing all the EnableQuery attributes on the controllers but that has no effect either. Since the EnableQuery attribute replaced the older Queryable attribute I am wondering if this is a Microsoft problem.

This question has been asked and not answered before: How limit OData results in a WebAPI

All help is greatly appreciated.

3 个答案:

答案 0 :(得分:2)

如果客户希望pagesize为10,并且想要第二页,则可以使用$ top和$ skip来实现目标:

localhost/odata/Customers?$top=10&$skip=10

关于动态设置pagesize:

public class MyEnableQueryAttribute : EnableQueryAttribute
{
    public override IQueryable ApplyQuery(IQueryable queryable, ODataQueryOptions queryOptions)
    {
        int pagesize = xxx;
        var result = queryOptions.ApplyTo(queryable, new ODataQuerySettings { PageSize = pagesize }); 
        return result;
    }
} 

并将此属性放在您的控制器方法中。

答案 1 :(得分:1)

您可以在webApiConfig resgister方法

中为MaxTop设置配置
public static class WebApiConfig{
      public static void Register(HttpConfiguration config){
          config.Select().Expand().Filter().OrderBy().MaxTop(100).count() // you can change max page size here
      }
}

答案 2 :(得分:0)

我能够通过创建扩展启用查询属性的新属性(我称为ConfigurableEnableQueryAttribute)来实现此目的。在该属性的构造函数中,加载配置文件并设置基础中您感兴趣的任何设置。我个人遍历我的appsettings的“ OData”部分中提供的所有设置,如果EnableQuery属性中有匹配的设置,我会将它们强制转换为指定的类型并提供它们,但是如果需要,您只能查找特定的设置

我的属性:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class ConfigurableEnableQueryAttribute : EnableQueryAttribute
{

    public ConfigurableEnableQueryAttribute()
    {
            var builder = new ConfigurationBuilder().AddJsonFile("appsettings.json");
            var configuration = builder.Build();

            var configProps = configuration.GetSection("OData").GetChildren();
            var baseProps = typeof(EnableQueryAttribute).GetProperties();

            foreach (var configProp in configProps)
            {
                var baseProp = baseProps.FirstOrDefault(x => x.Name.Equals(configProp.Key));

                if (baseProp != null)
                {
                    baseProp.SetValue(this, Convert.ChangeType(configProp.Value, baseProp.PropertyType));
                }
            }
    }
}

然后在控制器中

[HttpGet]
[ConfigurableEnableQuery]
public IQueryable<T> Get()
{
    return _context.Set<T>().AsQueryable();
}