Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"/$count" and "$count=true" doesn't work #1196

Closed
suadev opened this issue Jan 8, 2018 · 16 comments
Closed

"/$count" and "$count=true" doesn't work #1196

suadev opened this issue Jan 8, 2018 · 16 comments

Comments

@suadev
Copy link

suadev commented Jan 8, 2018

Hi,

It seems duplicate: #1189

But @ErliSoares 's solution doesn't work for me.

http://localhost:5021/api/v1/outboxdespatch/$count - > i got 404

http://localhost:5021/api/v1/outboxdespatch?$select=Id,Status&$count=true - > It ignores 'count=true'

capture

It's because of my NetCoreAll version is 2.0.0 ?

Packages
Microsoft.AspNetCore.All 2.0.0
Microsoft.AspNetCore.OData 7.0.0-beta1

@robward-ms
Copy link
Contributor

@suadev - AspNetCore 2.0 is supported, I would not expect that to be the issue. Since your issue is not resolved with work-around for other related issues, we should keep this one active until the root cause is known.

@ErliSoares
Copy link

It sounds like it's not your case, you're not calling the OData route, you have a problem for your control? [Route("api/[controller]")]

Show the control and configuration that is in the "ConfigureServices"

@suadev
Copy link
Author

suadev commented Jan 9, 2018

@ErliSoares, my controller and config like that;

Controller;

namespace ePlatform
{
    [ApiVersion("1.0")]
    [Route("api/v{version:apiVersion}/outboxdespatch")] 
    public class OutboxDespatchController : BaseController
    {
        [EnableQuery]
        [HttpGet]
        public  IActionResult Get()
        {
            var list = _despatchAdviceService.GetList(); //returns IQueryable<EirsaliyeOutboxDespatch>
            return Ok(list);
        }
    }
}

Configure;

        private static IEdmModel GetEdmModel(IServiceProvider serviceProvider)
        {
            var builder = new ODataConventionModelBuilder(serviceProvider);    
            builder.EntitySet<EirsaliyeOutboxDespatch>("despatchadvicelist");
            return builder.GetEdmModel();
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {         
            IEdmModel model = GetEdmModel(app.ApplicationServices);
            app.UseMvc(routeBuilder =>
            {
                routeBuilder.Select().Expand().Filter().OrderBy().MaxTop(100).Count();
                routeBuilder.MapODataServiceRoute("odataroute", "api", model);
                routeBuilder.EnableDependencyInjection();
            });
        }

Configure Service;

 public void ConfigureServices(IServiceCollection services)
   {
            services.AddApiVersioning(options =>
           {
                options.AssumeDefaultVersionWhenUnspecified = true;
                options.ReportApiVersions = true;
                options.DefaultApiVersion = new ApiVersion(1, 0);
            });			
            services.AddOData();        
   }

@suadev
Copy link
Author

suadev commented Jan 9, 2018

@robward-ms , I added my codes related with odata. Make sense?

@ErliSoares
Copy link

  1. Remove [Route("api/v{version:apiVersion}/outboxdespatch")] from controller.
  2. Chage builder.EntitySet<EirsaliyeOutboxDespatch>("despatchadvicelist"); to builder.EntitySet<EirsaliyeOutboxDespatch>("OutboxDespatch");.
  3. Acces http://localhost:5021/api/OutboxDespatch/$count

From what I understand, it has the following reasons, I do not know if it is library error or limitation

  1. When you use [Route ()] it looks like the is not called the OData route, but rather from ASP ...
  2. builder.EntitySet<EirsaliyeOutboxDespatch>("despatchadvicelist"); The name XX can not be different from the name of the controler. despatchadvicelist to OutboxDespatch
  3. In my case, I do not know why, but it is case sensitive, so in URl you have to be with 'OutboxDespatch'.

If it does not work, remove the versioning to see if it works

Sorry for my English

@suadev
Copy link
Author

suadev commented Jan 9, 2018

@ErliSoares, you are right, unfortunately it is case-sensitive and it doesn't work with controller's route. Thank you.

I got my response like below. Between, my response does not have '@odata.nextLink' value. How about yours?

@robward-ms , Do you have any comment about this routing issue, and missing '@odata.nextLink' value ?

request url: http://localhost:5021/api/OutboxDespatch?skip=1&$top=2&$count=true

response;

image

@vickityvik
Copy link

@suadev, I noticed in your initial Postman response it's only the array of OutboxDespatch objects, but your response above contains that plus the "@OData." properties. How did you get this to display? I am able to get a response only by adding the [Route()] attribute. If I remove it, I get "Resource not found for the segment". Could you please post an update version of your code after the changes suggested by @ErliSoares?

@suadev
Copy link
Author

suadev commented Jan 10, 2018

@vickityvik , the second one is right format. I mean odata format, and if you want to get your response with odata format, you have to be sure that you use odata routing instead of your controller route.

if your controller name is AbcXyzController, your config should be like below, (don't miss case-sensitive)

        private static IEdmModel GetEdmModel(IServiceProvider serviceProvider)
        {
            var builder = new ODataConventionModelBuilder(serviceProvider);
            builder.EntitySet<YourEntityClass>("AbcXyz");
            return builder.GetEdmModel();
        }


     public void Configure(IApplicationBuilder app, IHostingEnvironment env)
     {
            IEdmModel model = GetEdmModel(app.ApplicationServices);
            app.UseMvc(routeBuilder =>
            {
                routeBuilder.Select().Expand().Filter().OrderBy().MaxTop(100).Count();
                routeBuilder.MapODataServiceRoute("odataroute", "api", model);
                routeBuilder.EnableDependencyInjection();
            });
     }

@vickityvik
Copy link

Thanks @suadev. My code looks exactly the same... it must be something else. I cannot get to the Controller if I remove [Route()] from it.

It does work if it's there, but it does not contain any of the "@OData" values, only the array of objects.

I am looking at issue # #1189 as it's the same exception I am getting.

Thanks!

@genusP
Copy link
Contributor

genusP commented Jan 12, 2018

@vickityvik . Instead of RouteAttribute use ODataRoutePrefixAttributte and ODataRouteAttribute. See Attribute routing in docs

@robward-ms
Copy link
Contributor

Starting with initial issue from @suadev, the response from Jan 9th shows the count in the response so I'm guess that the comments from @ErliSoares got your controller working in OData. As @genusP points out, you need to use the ODataRoute* attributes instead of the RouteAttribute.

OData is case sensitive and we're missing the docs to configure case insensitivity (see #1231).

@suadev also added a question about '@odata.nextLink', which still seems to be in-answered. Is that a correct understanding of your issues?

@vickityvik, Seems like you are having a larger routing issue. Have you tried the suggestions from @genusP and if so, has it resolved your issue? If not, can you file a separate issue and include your code?

@robward-ms
Copy link
Contributor

@suadev - I see #1201 now for the @odata.nextLink issue. Let's use that for it's stated purpose and close this is $count is working as expected.

@suadev suadev closed this as completed Feb 8, 2018
@vickityvik
Copy link

@robward-ms - I ended up resolving my issue by adding the Route attribute to the non-OData methods and '[EnableQuery]' to OData ones, like so:

[HttpPost]
[Route("api/[controller]")]
public async Task<IActionResult> Create([FromBody] CreateOrganizationRequest createOrganizationRequest)
{
/// ...
}


[HttpGet]
[EnableQuery]
public async Task<GetOrganizationResponse> Get([FromODataUri] string key)
{
/// ...
}

@robward-ms
Copy link
Contributor

@vickityvik - Yep, that sounds like the right fix. Use [Route] for ASP.NET Core routing and [EnableQuery] on OData routing.

@xBorus
Copy link

xBorus commented Jul 9, 2018

When you use [Route ()] it looks like the is not called the OData route, but rather from ASP ...

Is there a way to make this work ? I use Odata in controllers that have many methods, i want to describe routes in the controller.

@kuttikrishnankodoth
Copy link

iam facing the same issue, i only have one method in the controller and thats the Odata end point. if i remove the route i am getting 404

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants