By glcheetham


2017-01-25 10:52:54 8 Comments

I'm using Microsoft.AspNet.OData v6.0.0 and expect that setting the MaxTop value to 10 will enable the $top query option.

However, requesting the URL http://localhost:23344/odata/v4/Resources?$top=10 still gives me the error:

{"error":{"code":"","message":"The query specified in the URI is not valid. The limit of '0' for Top query has been exceeded. The value from the incoming request is '10'.","innererror":{"message":"The limit of '0' for Top query has been exceeded. The value from the incoming request is '10'.","type":"Microsoft.OData.ODataException","stacktrace":"   at System.Web.OData.Query.Validators.TopQueryValidator.Validate(TopQueryOption topQueryOption, ODataValidationSettings validationSettings)\r\n   at System.Web.OData.Query.TopQueryOption.Validate(ODataValidationSettings validationSettings)\r\n   at System.Web.OData.Query.Validators.ODataQueryValidator.Validate(ODataQueryOptions options, ODataValidationSettings validationSettings)\r\n   at System.Web.OData.Query.ODataQueryOptions.Validate(ODataValidationSettings validationSettings)\r\n   at System.Web.OData.EnableQueryAttribute.ValidateQuery(HttpRequestMessage request, ODataQueryOptions queryOptions)\r\n   at System.Web.OData.EnableQueryAttribute.ExecuteQuery(Object response, HttpRequestMessage request, HttpActionDescriptor actionDescriptor, ODataQueryContext queryContext)\r\n   at System.Web.OData.EnableQueryAttribute.OnActionExecuted(HttpActionExecutedContext actionExecutedContext)"}}}

As though the top query still has a limit of 0.

Controller

public class ResourcesController : ODataController
{
    private IResourceService resourceService;
    public ResourcesController(IResourceService resourceService)
    {
        this.resourceService = resourceService;
    }

    [EnableQuery(MaxTop=10)]
    public IQueryable<Resource> Get()
    {
        return resourceService.GetResources().AsQueryable();
    }
    [EnableQuery]
    public SingleResult<Resource> Get([FromODataUri] int key)
    {
        var result = resourceService.GetResources().Where(r => r.Id == key).AsQueryable();

        return SingleResult.Create(result);
    }
}

WebApiConfig.cs

public static void Register(HttpConfiguration config)
{
    ODataConventionModelBuilder builder = new ODataConventionModelBuilder
    {
        Namespace = "MyNamespace",
        ContainerName = "DefaultContainer"
    };
    builder.EntitySet<Resource>("Resources");
    builder.EntityType<Resource>().Select().Count().Expand().OrderBy();
    config.MapODataServiceRoute(
        routeName: "ODataRoute",
        routePrefix: "odata/v4",
        model: builder.GetEdmModel());
}

What I've found

Github issue describing possible bug with behaviour of MaxTop

What does work

Every other query option I've enabled, including $skip.

What I've Tried

As in this question Setting config.Select().Expand().Filter().OrderBy().MaxTop(null).Count(); in the WebApiConfig.cs before config.mapODataServiceRoute(.... Didn't work.

Adding [Page(MaxTop = 100)] to my Resource model as in the same question. Didn't work.

Setting [Page] attribute on model. From WebApi OData documentation "if you set the Page Attribute, by default it will enable the $top with no-limit maximum value". Didn't work.

Setting [EnableQuery(PageSize=10)] attribute on controller. From WebApi OData documentation "if you set the Page Attribute, by default it will enable the $top with no-limit maximum value". Enabled paging but Didn't work.

The error says the limit was 0 for top in every case

2 comments

@Pawel 2017-03-01 12:49:47

I had the same issue and discovered that if you specify any rules in builder like you did.

builder.EntitySet<Resource>("Resources");
builder.EntityType<Resource>().Select().Count().Expand().OrderBy();

Value set by attribute will be overriden and set to 0.

If you remove those entries and put global configuration like

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

It will work.

Also you can define MaxTop using fluent interface on builder like this.

builder.EntityType<T>().Page(100, 100);

And it'll work even if you define other rules in builder for entity type.

Summarizing

It's probably caused that new configuration is created when you define some config in fluent builder interface and you cannot use attributes (EnableQueryAttribute on controller and Page on model).

It's probably a bug because they still recommend attribute approach. I will report it as issue on OData repository.

@glcheetham 2017-03-08 11:05:06

You're absolutely right: using global configuration only enables use of $top attribute. For reference, I think I found your issue: github.com/OData/WebApi/issues/928

@JZimmerman 2017-03-10 22:58:40

I think you're close. I've dug through the source code for the EnableQuery attribute and all I have to say is that it is all a big mess. In some places MaxTop is a nullable int, other places it isn't, so generally if you don't provide a value for MaxTop it automatically gets set to 0. This includes the attribute itself, the global configuration, and the EDM model. If I want to use [EnableAttribute] I have to address all of those places.

@JZimmerman 2017-03-10 23:06:17

OK, I take some of that back (but I cannot edit my comment). After a little more testing it appears that the minimum requirement if you want to use [EnableQuery] is to set the page size for the entity type. If you do just that (i.e. no global configuration nor MaxTop property for the attribute itself) things will work. To make matters worse there is no variation in the error message, etc., to give you any indication where the source for the MaxTop value is coming from. Simply maddening.

@shaijut 2017-08-10 08:24:49

Thanks, and for config.Select() to work add using System.Web.OData.Extensions; hope helps someone.

@silverfox1948 2017-09-10 23:08:31

setting the config globally solved my issue with maxtop.

@realbart 2019-11-08 11:42:11

I've seen some magic 'config' variable appear in three stackoverflow-articles now. Where does this come from? In my Configure(IApplicationBuilder app) I call UseMvc I have no "config" variable that has a method or extension "MaxCount"

@w.malgadey 2018-04-13 09:07:00

I had the same error. In my case I tried to hide a specific field from an entity with the Select(..) extension on EntityType<..>().

builder
    .EntityType<User>()
    .Select(System.Web.OData.Query.SelectExpandType.Disabled, "Password");

This happens inside my GetModel()-method. So I just changed the order in which I set the global settings:

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

IEdmModel model;
model = GetModel();

Related Questions

Sponsored Content

1 Answered Questions

[SOLVED] How limit OData results in a WebAPI

4 Answered Questions

[SOLVED] OData Exception The limit of '0' for Top query has been exceeded

2 Answered Questions

[SOLVED] Setting OData result Page Size at runtime in WebAPI app

1 Answered Questions

How to customize pageSize in RESTier?

1 Answered Questions

1 Answered Questions

1 Answered Questions

[SOLVED] Where does WebAPI 2.2 OData v4 [EnableQuery] apply?

1 Answered Questions

Using Paging Query Attribute in .NET Web API

2 Answered Questions

Sponsored Content