如何阻止OData 8命名约定自动重复控制器中的Action
解决OData 8自动生成路由导致的端点冲突问题
针对OData 8自动生成路由引发POST接口AmbiguousMatchException的问题,可通过以下几种方案解决:
1. 禁用OData默认动作路由约定,仅保留属性路由
在Program.cs的OData配置中,移除所有默认路由约定,只保留属性路由约定,让OData完全遵循你手动配置的路由规则,不再自动生成Action路由:
builder.Services.AddControllers() .AddOData(options => options.Select().Filter().OrderBy().Expand().Count().SetMaxTop(100) // 清除所有默认OData路由约定 .RemoveODataRoutingConventions() // 仅启用属性路由约定 .AddConventions(new AttributeRoutingConvention()));
2. 给非OData接口指定明确的唯一路由
给不需要OData功能的接口(比如POST)配置明确的路由,避免和OData自动生成的路由重叠。同时仅在需要OData功能的GET接口上添加[EnableQuery]属性:
[ApiController] [Route("api/[controller]")] public class WorkStationController : ControllerBase { // 启用OData功能的GET接口 [HttpGet] [EnableQuery] public IActionResult GetWorkStations() { // 业务逻辑 } // 普通POST接口,指定唯一路由 [HttpPost("create-workstation")] public IActionResult PostWorkStation([FromBody] WorkStation model) { // 业务逻辑 } }
3. 自定义路由约定,仅允许特定Action被OData处理
如果需要保留部分OData默认约定,可自定义路由规则,只让OData处理指定类型的Action(比如仅处理Get开头的方法):
首先创建自定义约定类:
public class CustomODataRoutingConvention : IODataControllerActionConvention { public bool AppliesToAction(ODataControllerActionContext context) { // 仅允许名称以Get开头的Action被OData处理 return context.ActionDescriptor.ActionName.StartsWith("Get", StringComparison.OrdinalIgnoreCase); } public bool AppliesToController(ODataControllerActionContext context) { return true; // 对所有控制器生效 } }
然后在Program.cs中添加这个自定义约定:
builder.Services.AddControllers() .AddOData(options => options.Select().Filter().OrderBy().Expand().Count().SetMaxTop(100) .AddRoutingConventions(new List<IODataRoutingConvention> { new AttributeRoutingConvention(), new CustomODataRoutingConvention() }));
内容的提问来源于stack exchange,提问作者Simon
相关产品推荐
相关产品推荐

