目前尚不完全清楚是做什么BuildEdmModel()
的,但看起来您是手动构建它而不是通过VersionedODataModelBuilder。这是允许的,但要知道您需要设置ApiVersionAnnotation。OData 的 API 版本控制使用每个 API 版本的 EDM方法,使所有内容都清晰隔离。API 版本控制通过将应用的ApiVersionAnnotation与已解析的传入 API 版本进行比较来确定如何匹配 EDM 。“只可以有一个人。”
如果您自己构建 EDM,则需要将此必需的注释添加到模型本身:
edm.SetAnnotationValue(edm, new ApiVersionAnnotation(new ApiVersion(1, 0)));
如果你只有一个版本,这很容易构建。如果您有多个版本,它会变得更加复杂。VersionedODataModelBuilder通过创建一组所有 API 版本的联合集来实现这一点,来自所有 OData API,通过IActionDescriptorCollectionProvider发现。对于每个发现的 OData API 版本,一组IModelConfiguration实例用于在特定 API 版本中应用该特定 EDM 的配置,不包括任何内容(例如排除)。这是由实施者(例如开发者)决定的。根据应用程序的复杂性,您可以使用单个IModelConfiguration,每个实体一个,或者根本不使用,只使用VersionedODataModelBuilder.DefaultModelConfiguration
回调。
无论您使用哪种方法,如果设置了ApiVersionAnnotation,您将重新开始工作。
更新:响应添加的图像。
还有几个额外的点:
- 如果您从 DI注入 VersionedODataModelBuilder或从IServiceProvider显式解析它,所有工作都已为您完成。
- 如果您只是将VersionedODataModelBuilder作为参数传递给
MapVersionedODataRoute
它,它将做正确的事情。由于 OData 的前缀概念,IModelConfiguration可能因 API 版本和路径而异。或者,您可以调用VersionedODataModelBuilder.GetEdmModels('path')
. 如果前缀之间没有区别,那么你很好。
- 主要问题似乎是您的控制器名称不匹配。API 版本控制按控制器名称整理 API,因为 - 嗯 - 它是唯一可以使用的一致且可靠的东西。这对于匹配相应的 EDM 也很重要。目前尚不清楚PaymentsODataRouteAttribute的实际作用;但是,如果它设置了
controller
路由参数,那么它应该可以工作。如果不是,那么您的控制器名称需要匹配,或者您可以使用提供[ControllerName("payments")]
的来满足要求。我假设相应实体集的名称是Payments
.
- 不知道EnableODataAttribute是什么。这似乎不是标准属性。从ODataController继承将启用 OData 功能。
- OData 不支持开箱即用的 API Explorer。如果您还没有使用 OData 的 API 版本控制 API Explorer 扩展,则配置
[ApiExplorerSettings(IgnoreApi = false)]
可能会在运行时导致错误。API 版本控制扩展知道ODataController明确选择退出API Explorer。默认情况下,它将完全忽略该IgnoreApi
设置,因此您不必重新配置和选择每个ODataController。如果你真的想使用ApiExplorerSettingsAttribute,那么你可以配置 API Explorer 扩展来支持它ODataApiExplorerOptions.UseApiExplorerSettings
,默认为false
. 如果您不将其更改为true
,该设置将被完全忽略,其中可能包括您有意标记为 的控制器IgnoreApi = true
。