ASP.NET Core OData 8.0自定义路由端点注册失败求助
解决方案:ASP.NET Core OData 8.0 RC自定义控制器路由
核心原理
OData 8.0的路由系统基于EDM模型中的实体集/操作名称匹配,而非直接依赖控制器类名或普通[Route]属性。普通[Route]属性会将控制器纳入MVC路由体系,而非OData路由体系,这就是你看到路由被归类为非OData端点的原因。
正确配置步骤
1. 显式配置EDM模型的实体集名称
在构建EDM模型时,将实体集名称设置为你想要的自定义路由名(比如AnyOtherRouteName):
public IEdmModel GetEdmModel() { ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); // 显式指定实体集名称为自定义路由名 builder.EntitySet<ExampleAEntityDto>("AnyOtherRouteName"); return builder.GetEdmModel(); }
2. 控制器与实体集关联(二选一)
方式一:使用约定路由(推荐)
不需要给控制器添加[Route]属性,只需确保控制器继承OData控制器基类,并通过OData端点配置显式映射控制器到实体集:
// 控制器类名可以任意,无需和实体集名称一致 public class PresentationLayerExampleAEntityOData03Controller : ModuleQueryableODataControllerBase<ExampleAEntityDto> { [HttpGet] [EnableQuery] public IActionResult Get() { // 业务逻辑 } [HttpGet("{id}")] public IActionResult Get(int id) { // 业务逻辑 } }
在端点配置中,添加控制器与实体集的映射:
app.UseEndpoints(endpoints => { // 配置OData路由前缀 var odataRoute = endpoints.MapODataRoute( routeName: "ODataRoute", routePrefix: "api/odata/v{version}", model: GetEdmModel() ).EnableDependencyInjection(); // 显式映射控制器到目标实体集名称 odataRoute.MapODataControllerRoute<PresentationLayerExampleAEntityOData03Controller>("AnyOtherRouteName"); });
方式二:使用属性路由(手动指定OData格式路由)
如果必须使用属性路由,需要遵循OData的路由模板格式,并且确保路由与EDM模型匹配,同时添加[EnableQuery](如果需要OData查询功能):
public class PresentationLayerExampleAEntityOData03Controller : ModuleQueryableODataControllerBase<ExampleAEntityDto> { [HttpGet] [Route("api/odata/v{version}/AnyOtherRouteName")] [EnableQuery] public IActionResult Get() { // 业务逻辑 } [HttpGet] [Route("api/odata/v{version}/AnyOtherRouteName({id})")] public IActionResult Get(int id) { // 业务逻辑 } }
注意:这种方式需要手动维护每个动作的路由模板,不如约定路由灵活。
对你疑问的解答
- 不用
[Route]时正常工作:因为OData默认会将控制器类名去掉Controller后缀后,匹配EDM模型中的实体集名称,自动纳入OData路由体系。 [Route]属性不会被OData路由读取:[Route]属于MVC路由体系,OData路由依赖EDM模型的元数据匹配,两者不兼容,添加后控制器会被当作普通MVC控制器处理。- 端点与约定不符导致异常:OData路由有严格的格式要求,必须与EDM模型中的实体集/操作定义匹配,不符合约定的路由无法被OData路由系统识别,会被归类为非OData端点或无法匹配。
内容的提问来源于stack exchange,提问作者Sky
相关产品推荐
相关产品推荐

