ASP.NET Core API 版本控制 - 所有版本都使用相同的控制器

问题描述

我有一个 ASP.NET Core 3.1 API,我要为我的一个控制器推出一个新版本。 我正在使用 Microsoft.AspNetCore.Mvc.Versioning NuGet 包,并且我已将新版本设置为认版本。 我所有的其他控制器都应该适用于旧版本 (1.0) 和新版本 (1.1)。

例如:

    [ApiVersion("1.0",Deprecated = true)]
    public class MySampleController
    {
    }
    
    [ApiVersion("1.1")]
    public class MynewsampleController
    {
    }

    [ApiVersion("1.0",Deprecated = true)]
    [ApiVersion("1.1")]
    public class AllOtherController
    {
    }

问题:
我真的必须将所有版本添加到所有控制器吗?
有没有更好/正确的方法来处理这个问题?

我曾尝试使用 [ApiVersionNeutral] 但这似乎不正确,根据 documentation,仅应在特殊情况下使用。 如果我不添加 [ApiVersion] 属性,它认为新的 1.1 版本,1.0 不再有效。

由于这是我的第一个 SO 问题,我希望它符合指南:)

解决方法

问:我真的必须将所有版本添加到所有控制器吗?

答:是的。 API 版本是离散的。如果服务器不能满足请求,客户端应该得到他们所要求的内容和适当的错误响应。

问:有没有更好/正确的方法来处理这个问题?

答:有几种可能的选择。 更好或更正确的处理方式是非常主观的。有很多因素,最终的决定可能会归结为偏好。

一个常见的误解是 API 版本控制使用属性。它真的不关心属性,它只是一种可能性,并且倾向于作为元数据与开发人员产生共鸣。您可以选择使用现成的属性、自定义属性、现成的约定或您自己的自定义约定。

选择如何应用版本元数据通常是偏好和实际管理。一个常见的场景是按 API 版本在文件夹中组织控制器。在多种 .NET 语言中,文件夹名称会转换为部分或全部相应命名空间。这种安排很常见,因此有一个开箱即用的 VersionByNamespaceConvention。有关详细信息,请参阅 documentationBy Namespace Sample 还演示了如何端到端地启动此类项目。

API 版本中立 意味着 API 接受任何和所有版本,包括根本没有。它可能意味着您不关心 API 版本,或者您接受您自己处理的整个范围。它实际上仅适用于永远不会随时间变化的 API。例如,HTTP DELETE 操作通常不会随时间或跨版本而改变。

您的意思不是 100% 清楚:

“如果我不添加 [ApiVersion] 属性,它默认为新的 1.1 版本,1.0 不再有效。”

本身没有默认值。此语句似乎暗示您已将 AssumeDefaultVersionWhenUnspecified 选项设置为 true。您应该不要这样做,除非您有充分的理由这样做。这可能是 API 版本控制最常被滥用的功能之一。客户端必须知道它要求的版本。允许客户端不指定版本并使事物从 1.0 过渡到 1.1 会破坏客户端。服务器不能假设它不会。此功能旨在为以前未定义明确版本的现有服务中的祖父服务。该场景仅在首次启用 API 版本控制时存在。如上所述,所有控制器必须具有一个或多个离散的 API 版本,但原始 API 集并没有明确定义它。如果此功能不存在,那么不知道 API 版本的基准客户端集就会中断。