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

ASP.NET Core API Versioning - Same controller for all versions

我有一个 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
    {
    }

问题:
我真的必须将所有版本添加到所有控制器吗?
有 better/correct 的处理方法吗?

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

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

Q: Do I really have to add all versions to all controllers?

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

Q: Is there a better/correct way of handling this?

A: 有几种可能的选择。 更好或更正确处理事情的方式是非常主观的。有很多因素,最终决定可能只取决于偏好。

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

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

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

不是 100% 清楚你的意思:

"If I do not add the [ApiVersion] attribute, it defaults to the new 1.1 version and 1.0 no longer works."

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