使用 OData 8 设置自定义路由
Set custom route using OData 8
最近我更新到 OData 8.0.10。我在我的 Startup.cs
文件中添加了这个:
services.AddRouting();
services.AddControllers().AddOData(opt =>
opt.AddRouteComponents("odata", GetEdmModel()).Filter().Select().OrderBy().Count());
哪里
private static IEdmModel GetEdmModel()
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Project>("Project");
return builder.GetEdmModel();
}
我有这个小控制器
[Route("api/[controller]")]
[ApiController]
public class ProjectController : ControllerBase
{
[HttpGet]
[EnableQuery(PageSize = 20)]
public IQueryable<Project> GetAsync()
{
var projects = _projectRepository.GetAll();
return projects;
}
[HttpGet("{id}", Name = "GetProjectById")]
public async Task<ActionResult> GetAsyncById(long id)
{
var project = await _projectService.GetProjectByIDAsync(id);
return Ok(project);
}
[HttpPatch("{id}", Name = "PatchProjectById")]
public async Task<ActionResult> PatchProject(long id, [FromBody] ProjectPatchDetails projectPatch)
{
var project = await _projectRepository.GetAsync(id);
var updated = await _projectService.UpdateProjectAsync(id, project, projectPatch);
return Ok(updated);
}
}
具有三个端点,其中一个由 [EnableQuery]
注释,其余则没有。当我访问 api/project?$count=true&$skip=0&$orderby=CreateDate%20desc
时,我得到一个分页信息(20 条记录),但我没有得到 @odata.context 和 @odata.count。如果我使用 odata/
前缀访问 /odata/project?$count=true&$skip=0&$orderby=CreateDate%20desc
,它会给我 @odata.context 和 @odata.count。我尝试将 AddRouteComponents
更改为 AddRouteComponents("api", GetEdmModel())
但在这种情况下我收到以下错误:
"The request matched multiple endpoints. Matches: MyApp.Api.Controllers.ProjectController.GetAsync (MyApp.Api) MyApp.Api.Controllers.ProjectController.GetAsync (MyApp.Api)"
在这种情况下我有多个问题:
- 有没有办法将 odata 重新路由到 api,将 /odata 前缀设为 /api 并使其工作?
- 我是否应该制作另一个控制器来存储所有 OData 标记的操作,如果可能的话,这样可能会解决这个问题?
我认为您的 ProjectController
应该继承自 ODataController
而不是 ControllerBase
。使用 ODataController,您应该获得 context url
和 @odata.count
@anthino
- 有没有办法将 odata 重新路由到 api,将 /odata 前缀设为 /api 并使其工作?
如果加了'opt.AddRouteComponents("api", GetEdmModel())',记得去掉
[Route("api/[controller]")]等属性路由
- 我是否应该创建另一个控制器来存储所有 OData 标记的操作,如果可能的话,这样可能会解决这个问题?
基本上,最好创建两个控制器,一个用于odata,另一个用于其他。在您的场景中,您将它们混合在一起。你应该小心这一点。您可以使用 'app.UseODataRouteDebug()' 中间件来帮助您调试。
最近我更新到 OData 8.0.10。我在我的 Startup.cs
文件中添加了这个:
services.AddRouting();
services.AddControllers().AddOData(opt =>
opt.AddRouteComponents("odata", GetEdmModel()).Filter().Select().OrderBy().Count());
哪里
private static IEdmModel GetEdmModel()
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Project>("Project");
return builder.GetEdmModel();
}
我有这个小控制器
[Route("api/[controller]")]
[ApiController]
public class ProjectController : ControllerBase
{
[HttpGet]
[EnableQuery(PageSize = 20)]
public IQueryable<Project> GetAsync()
{
var projects = _projectRepository.GetAll();
return projects;
}
[HttpGet("{id}", Name = "GetProjectById")]
public async Task<ActionResult> GetAsyncById(long id)
{
var project = await _projectService.GetProjectByIDAsync(id);
return Ok(project);
}
[HttpPatch("{id}", Name = "PatchProjectById")]
public async Task<ActionResult> PatchProject(long id, [FromBody] ProjectPatchDetails projectPatch)
{
var project = await _projectRepository.GetAsync(id);
var updated = await _projectService.UpdateProjectAsync(id, project, projectPatch);
return Ok(updated);
}
}
具有三个端点,其中一个由 [EnableQuery]
注释,其余则没有。当我访问 api/project?$count=true&$skip=0&$orderby=CreateDate%20desc
时,我得到一个分页信息(20 条记录),但我没有得到 @odata.context 和 @odata.count。如果我使用 odata/
前缀访问 /odata/project?$count=true&$skip=0&$orderby=CreateDate%20desc
,它会给我 @odata.context 和 @odata.count。我尝试将 AddRouteComponents
更改为 AddRouteComponents("api", GetEdmModel())
但在这种情况下我收到以下错误:
"The request matched multiple endpoints. Matches: MyApp.Api.Controllers.ProjectController.GetAsync (MyApp.Api) MyApp.Api.Controllers.ProjectController.GetAsync (MyApp.Api)"
在这种情况下我有多个问题:
- 有没有办法将 odata 重新路由到 api,将 /odata 前缀设为 /api 并使其工作?
- 我是否应该制作另一个控制器来存储所有 OData 标记的操作,如果可能的话,这样可能会解决这个问题?
我认为您的 ProjectController
应该继承自 ODataController
而不是 ControllerBase
。使用 ODataController,您应该获得 context url
和 @odata.count
@anthino
- 有没有办法将 odata 重新路由到 api,将 /odata 前缀设为 /api 并使其工作?
如果加了'opt.AddRouteComponents("api", GetEdmModel())',记得去掉 [Route("api/[controller]")]等属性路由
- 我是否应该创建另一个控制器来存储所有 OData 标记的操作,如果可能的话,这样可能会解决这个问题?
基本上,最好创建两个控制器,一个用于odata,另一个用于其他。在您的场景中,您将它们混合在一起。你应该小心这一点。您可以使用 'app.UseODataRouteDebug()' 中间件来帮助您调试。