【问题标题】:Setting OData result Page Size at runtime in WebAPI app在 WebAPI 应用程序运行时设置 OData 结果页面大小
【发布时间】:2017-01-08 00:46:59
【问题描述】:

我正在使用 OdataControllers 编写一个 ASP.NET Web API 2 Web 服务,我发现了如何使用 EnableQueryAttributePageSize Property 设置页面大小。我想允许我的 Web 服务的用户在 app.config 中设置页面大小,然后让应用程序读取此设置并设置页面大小。问题是使用该属性需要将 Page Size 设置为编译时间常数。

属性的使用:

[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 集合保持为空。

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

这个问题之前有人问过,但没有回答过:How limit OData results in a WebAPI

非常感谢所有帮助。

【问题讨论】:

  • 有点混乱。用户发出 web-api 请求,并且您希望该 api 请求修改 app.config 文件?你确定这是个好主意吗?
  • 我已经扩展了我的问题以澄清。我想从 app.config 中读取值并在运行时设置它。

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


【解决方案1】:

我能够通过创建一个扩展启用查询属性的新属性(我称之为 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();
}

【讨论】:

    【解决方案2】:

    您可以在 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
          }
    }
    

    【讨论】:

      【解决方案3】:

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

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

      关于动态设置页面大小:

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

      并将这个属性放在你的控制器方法中。

      【讨论】:

      • 我知道 OData 语法。我想限制(按页面大小)客户端允许从服务器请求的数据量。
      • 更新:如果被调用者未对查询应用任何过滤(例如 $top、$filter 等),则不会调用 IQueryable ApplyQuery 覆盖。我仍在寻找始终有效的解决方案。
      猜你喜欢
      • 2017-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-27
      • 2010-10-20
      • 1970-01-01
      • 2022-11-08
      • 1970-01-01
      相关资源
      最近更新 更多