0

我收到与 OData API 版本控制相关的应用程序启动异常。异常消息:

实体模型 (EDM) 没有所需的 ApiVersionAnnotation 注解

映射版本化的 odata 路由的片段

 public static IEndpointRouteBuilder MapPaymentsODataRoute(this IEndpointRouteBuilder builder)
    {
        builder.MapVersionedODataRoute(
            "payments-odata",
            "api/v{apiVersion:apiVersion}/payment-service/odata",
            new List<IEdmModel> { BuildEdmModel() });
    
        return builder;
    }

在 DI 容器中注册的所有需要​​的 API 版本控制服务。

见端点配置: 端点配置

请参阅控制器示例: 控制器示例

有什么想法吗?有什么问题?

4

1 回答 1

0

目前尚不完全清楚是做什么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
于 2021-09-27T21:06:30.617 回答