设置WebAPI 2 OData服务的默认页面大小

时间:2017-01-31 15:45:31

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

我有一个ODataController,其端点如下:

[EnableQuery]
public IQueryable<Customer> Get()
{
    return _context.Customers;
}

WebApiConfig的Register方法中的此设置:

config.Count().Filter().OrderBy().Expand().Select().MaxTop(100);

有很多客户条目,我不希望客户端一次请求太多,因为查询需要很长时间。幸运的是,这个设置意味着他们是否提出了这样的请求:

http://domain.com/api/Customers?$顶= 1000

它会阻止他们检索它们,因为它高于100.

但是,如果他们这样做了一个请求:

http://domain.com/api/Customers

然后尝试检索我不想要的所有客户。

我知道我可以像这样设置页面大小:

[EnableQuery(PageSize = 10)]
public IQueryable<Customer> Get()
{
    return _context.Customers;
}

这只会返回10个结果,但是我仍然希望用户能够为分页指定自己的$ top和$ skip值(并决定他们每页需要多少结果)。我想要的是最多100个,默认值为10.

我怎样才能做到这一点?

修改

我尝试了以下操作,但在使用Expand子句时它无法正常工作。还有其他想法吗?

[EnableQuery(MaxTop = 100)]
public IQueryable<Customer> Get(ODataQueryOptions<Customer> queryOptions)
{
    IQueryable<Customer> query = _context.Customers;
    int? top = queryOptions?.Top?.Value;
    if (top == null)
    {
        query = query.Take(10);
    }

    return query;
}

2 个答案:

答案 0 :(得分:0)

我面对同样的事情,但我能够让它发挥作用。看起来参数的顺序很重要。你必须原谅我,我在这方面很陌生,在我学习的同时学习,所以我希望这实际上有所帮助。

我的API控制器如下所示:

    [EnableQuery(PageSize=100)]
    public IQueryable<APPLICATION_LOGS> Get()
    {
        return db.APPLICATION_LOGS;
    }

在我的客户端,我正在构建请求并捕获响应:

        string entity = "/AuditApplicationLog";
        string expandOptions = "&$expand=APPLICATION, APPLICATIONS_SUBSYSTEMS, FILE";
        string parameters = "?$top=100&$count=true";
        string url = serviceUri + entity + parameters + expandOptions;
        WebRequest request = WebRequest.Create(url);
        WebResponse response = request.GetResponse();

这是我刚刚用来教自己一些概念的练习项目。我的API控制器中的页面大小设置为100但是你在参数变量中注意到我设置了一个最高值。如果我将此值设置为25,它将返回25.如果我将其设置为50,它将返回50等。显然,我设置参数的顺序很重要。如果我在展开参数之前设置顶部值,它就可以工作。如果我尝试在扩展参数之后设置它,它将返回默认值100,无论我设置的值是什么。它确实似乎忽略了&#34; nextPage&#34;链接,但这可以解释。我希望这会有所帮助。

答案 1 :(得分:0)

定义课程:

public class EnableQueryWithDefaultPageSizeAttribute : EnableQueryAttribute
{
    const int pageSizeDefault = 10;

    public override IQueryable ApplyQuery(IQueryable queryable, ODataQueryOptions queryOptions)
    {
        int? top = queryOptions?.Top?.Value;
        if (top == null)
        {
            return queryOptions.ApplyTo(queryable, new ODataQuerySettings { PageSize = this.PageSize == 0 ? pageSizeDefault : this.PageSize });
        }

        return queryOptions.ApplyTo(queryable); ;
    }
}

并使用它的 EnableQuery 实例。参见this