OData 8.x搭配Route属性时同一控制器方法生成重复路由问题求助
问题原因
- 你的配置确实存在冲突:同时启用了ASP.NET Core原生属性路由、OData约定路由两套路由解析逻辑,两者对同一个控制器动作生成了路径、请求方法完全一致的两个端点,最终触发Swagger的冲突校验错误。
- 具体触发点:你在控制器上加了
[Route("api/[controller]")]属性,同时OData配置里通过AddRouteComponents("api", GetEdmModel())指定了OData路由前缀为api,EdmModel里的EntitySet名和控制器名都是WeatherForecasts,两套逻辑生成的路由都是GET api/WeatherForecasts,完全重复。
解决方案
方案1(最推荐,仅用OData处理路由)
直接删除控制器上的[Route]特性、动作上的[HttpGet]等原生路由特性即可。OData会根据你配置的EdmModel、路由前缀自动生成对应路由,不需要额外手动加属性路由,不会再生成重复端点。
修改后的控制器代码示例:
public class WeatherForecastsController : ODataController{ private static readonly string[] Summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; public IEnumerable<WeatherForecast> Get() { var rng = new Random(); return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateTime.Now.AddDays(index), TemperatureC = rng.Next(-20, 55), Summary = Summaries[rng.Next(Summaries.Length)] }) .ToArray(); } }
方案2(同时保留原生路由和OData路由)
修改OData的路由前缀和原生属性路由的前缀做区分,避免路径重复。比如把OData的配置修改为:
.AddOData(opt => { opt .Count() .Filter() .Select() .OrderBy() .SetMaxTop(20) .AddRouteComponents("odata", GetEdmModel()); // 前缀改为odata,和原生的api区分 });
这样OData生成的路由为GET odata/WeatherForecasts,原生属性路由生成的是GET api/WeatherForecasts,路径不同不会冲突。
方案3(临时 workaround,不推荐)
如果不想修改路由配置,可以在Swagger的配置里添加冲突解决逻辑,让Swagger只保留第一个匹配的端点:
services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "SwaggerODataTest", Version = "v1" }); // 新增冲突解决配置 c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First()); });
注意该方案只是规避了Swagger的报错,本质上应用内还是存在两个重复的端点,可能会导致后续路由匹配逻辑异常。
内容的提问来源于stack exchange,提问作者Jason
相关产品推荐
相关产品推荐

