I have an ASP.NET Core 8 Web API project and want to add an ODataController
in the Controllers/OData
folder. I already have a Controllers/ProjectsController.cs
file and want to create a Controllers/OData/ProjectsController.cs
file for the ODataController
.
However, it's not working. When I call it ODataProjectsController
, it works.
I then have the following pieces of code - program.cs
:
var modelBuilder = new ODataConventionModelBuilder();
modelBuilder.EntitySet<ProjectDto>("ODataProjects");
builder.Services.AddControllers().AddOData(
options => options.Select().Filter().OrderBy().Expand().Count().SetMaxTop(null).AddRouteComponents(
"odata",
modelBuilder.GetEdmModel()));
Controllers/OData/ODataProjectsController.cs
(using AutoMapper):
public class ODataProjectsController : ODataController
{
private readonly MyDbContext _db;
private readonly IMapper _mapper;
public ODataProjectsController(MyDbContext db, IMapper mapper)
{
_db = db;
_mapper = mapper;
}
[HttpGet]
public async Task<ActionResult> Get(ODataQueryOptions<ProjectDto> options)
{
var projects = await _db.ProjectEntities.GetQueryAsync(_mapper, options);
return Ok(projects);
}
}
That works great. But when I change my ODataProjectsController
to ProjectsController
(still in the OData
subfolder) and my entity set name to Projects
, I get an error:
Endpoint Backend.Api.Controllers.ProjectsController.Get (Backend.Api) contains authorization metadata, but a middleware was not found that supports authorization.
This makes me think ASP.NET Core 8 is confusing the two controllers? Is it even possible to put my OData
controllers in a subfolder? I've tried messing about with the ODataRouteComponentAttribute
but nothing seemed to work.
Ah, the fix was simple. I was using the wrong attribute. I should use the regular RouteAttribute
from ASP.NET Core MVC.
I also seem to have to name my entityset with lowercase.
So this is the code that works for me:
Program.cs
:
var modelBuilder = new ODataConventionModelBuilder();
modelBuilder.EntitySet<ProjectDto>("projects");
builder.Services.AddControllers().AddOData(
options => options.Select().Filter().OrderBy().Expand().Count().SetMaxTop(null).AddRouteComponents(
"odata",
modelBuilder.GetEdmModel()));
Controllers/OData/ProjectsController.cs
:
[Route("odata/projects")]
public class ProjectsController : ODataController
{
private readonly MyDbContext _db;
private readonly IMapper _mapper;
public ProjectsController(MyDbContext db, IMapper mapper)
{
_db = db;
_mapper = mapper;
}
[HttpGet]
public async Task<ActionResult> Get(ODataQueryOptions<ProjectDto> options)
{
var projects = await _db.ProjectEntities.GetQueryAsync(_mapper, options);
return Ok(projects);
}
}