Getting OData Count in ASP.NET Core WebAPI Getting OData Count in ASP.NET Core WebAPI asp.net asp.net

Getting OData Count in ASP.NET Core WebAPI


I could reproduce your issue when i use [Route("api/[controller]")]and [ApiController] with the startup.cs like below:

app.UseMvc(routeBuilder =>        {            routeBuilder.Expand().Select().Count().OrderBy().Filter();            routeBuilder.EnableDependencyInjection();        });

To fix it,be sure you have built a private method to do a handshake between your existing data models (OData model in this case) and EDM.

Here is a simple demo:

1.Controller(comment on Route attribute and ApiController attribute):

//[Route("api/[controller]")]//[ApiController]public class StudentsController : ControllerBase{    private readonly WSDbContext _context;    public StudentsController(WSDbContext context)    {        _context = context;    }    // GET: api/Students    [HttpGet]    [EnableQuery()]    public IEnumerable<Student> Get()    {        return _context.Students;    }}//[Route("api/[controller]")]//[ApiController]public class SchoolsController : ControllerBase{    private readonly WSDbContext _context;    public SchoolsController(WSDbContext context)    {        _context = context;    }    // GET: api/Schools    [HttpGet]    [EnableQuery()]    public IEnumerable<School> Get()    {        return _context.Schools;    }

2.Startup.cs():

public class Startup{    public Startup(IConfiguration configuration)    {        Configuration = configuration;    }    public IConfiguration Configuration { get; }    // This method gets called by the runtime. Use this method to add services to the container.    public void ConfigureServices(IServiceCollection services)    {        services.AddMvcCore(action => action.EnableEndpointRouting = false);        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);        var connection = @"Server=(localdb)\mssqllocaldb;Database=WSDB;Trusted_Connection=True;ConnectRetryCount=0";        services.AddDbContext<WSDbContext>(options => options.UseSqlServer(connection));        services.AddOData();    }    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.    public void Configure(IApplicationBuilder app, IHostingEnvironment env)    {        if (env.IsDevelopment())        {            app.UseDeveloperExceptionPage();        }        else        {            app.UseHsts();        }        app.UseHttpsRedirection();        app.UseMvc(routeBuilder =>        {            routeBuilder.Expand().Select().Count().OrderBy().Filter();            routeBuilder.MapODataServiceRoute("api", "api", GetEdmModel());        });    }    private static IEdmModel GetEdmModel()    {        var builder = new ODataConventionModelBuilder();        builder.EntitySet<Student>("Students");        builder.EntitySet<Student>("Schools");        return builder.GetEdmModel();    }}


Just been battling this.

I found that if I request my controller at /api/Things that most of the OData options work but $count doesn't.

However, $count does work if I request the same method via /odata/Things.


You can just set an empty preffix route when you map OData, and you will receive OData with your request your endpoint.

routeBuilder.MapODataServiceRoute("ODataEdmModel", "", GetEdmModel());