在 WebAPI 应用程序中运行时设置 OData 结果页面大小

问题描述 投票:0回答:4

我正在使用 OdataController 编写 ASP.NET Web API 2 Web 服务,我已经找到了如何使用 PageSize Property EnableQueryAttribute 设置页面大小。我想允许我的 Web 服务的用户在 app.config 中设置页面大小,然后让应用程序读取此设置并设置页面大小。问题是使用该属性需要将“页面大小”设置为编译时常量。

属性的使用:

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

我见过的一个建议解决方案是构造 EnableQueryAttribute 并将其设置在 HTTPConfiguration 配置对象上,如下所示

int customSize = ReadPageSizeSettingFromConfigFile();

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

但这实际上不起作用。 HttpConfiguration 的 Filter 集合保持为空。

另一篇文章的评论(隐藏在评论列表中)建议删除控制器上的所有 EnableQuery 属性,但这也没有效果。由于 EnableQuery 属性取代了旧的 Queryable 属性,我想知道这是否是 Microsoft 的问题。

这个问题之前已经被问过,但没有得到解答:如何限制 OData 结果在 WebAPI 中

非常感谢所有帮助。

asp.net asp.net-web-api2 odata
4个回答
5
投票

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

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

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


3
投票

您可以在 webApiConfig 注册方法中设置 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
投票

我能够通过创建一个扩展启用查询属性的新属性(我将其称为 ConfigurableEnableQueryAttribute)来实现此目的。在该属性的构造函数中,加载您的配置文件并在基础中设置您感兴趣的任何设置。就我个人而言,我循环遍历应用程序设置的“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();
}

0
投票

如果您想直接从查询字符串读取数据并设置页面大小,那么以下代码片段可能会帮助您。在这里,我将 pagesize 作为查询的可选参数(不是 Odata 查询字符串)传递,并用于定义页面大小。如果未通过,则使用默认值-

[HttpGet]
    [EnableQuery]
    public ActionResult<IQueryable<Order>> Get(ODataQueryOptions<Order> options, int? pagesize)
    {
        if(pagesize != null)
        {
            var settings = new ODataQuerySettings()
            {
                PageSize = pagesize,
            };

            var results = options.ApplyTo(_context.Orders.AsNoTracking().AsQueryable(), settings);

            return Ok(results);
        }
        else
        {
            return Ok(_context.Orders.AsNoTracking().AsQueryable());
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.