使用嵌套在中的标准化 RoutingAttribute 创建自定义 ControllerAttribute

Create a custom ControllerAttribute with a standardized RoutingAttribute nested in

在我的每个控制器的顶部,我都有这些属性:

[Route("api/[controller]")]
[ApiController]
[Produces("application/json")]

我正在尝试合并它们,并向控制器添加“版本”的概念。

例如,如果我的 api 有所改进,我不希望我的所有应用程序都因为重大更改而崩溃。所以我希望路由为 /api/v1/[controller],如果我更新它,我将创建一个带有 /api/v2/[controller] 路由的新控制器。两条路线将同时可用,我将能够逐步更新我的应用程序以连接到 api 的 v2 而不会出现任何崩溃。

这是我正在处理的代码:

[Route($"api/v{ApiVersion}/[controller]")]
[Produces("application/json")]
public class ExtendedApiControllerAttribute : ApiControllerAttribute
{
    public string ApiVersion { get; set; }

    public ExtendedApiControllerAttribute(string apiVersion): base()
    {
        ApiVersion = apiVersion;
    }
}

但是我遇到了很多问题。

首先,我不能像我想的那样轻松地引用 ApiVersion 字段。我收到此错误:

An object reference is required for the non-static field, method, or property 'ExtendedApiControllerAttribute.ApiVersion'

但即使我只是忽略“版本控制”系统,并在 ExtendedAttribute 上切换到简单的路由系统 [Route("api/[controller]")],也无法访问控制器。当我尝试访问相应的端点时出现 404 错误(即使它仍然可以通过 Swagger 使用)。

如何将这些功能合并到一个独特的属性中,就像这样:[ExtendedApiController("1")]

一般来说,对于 ASP.NET Core Web API 版本,我们可以使用 Microsoft.AspNetCore.Mvc.Versioning 包。您可以参考以下步骤:

  1. 通过 NuGet 安装 Microsoft.AspNetCore.Mvc.Versioning 包。

  2. 在ConfigureServices方法中注册ReportApiVersions服务(在asp.net5,如果你使用的是Asp.net6,可以在Program.cs文件中添加).

     public void ConfigureServices(IServiceCollection services)
     {
    
         services.AddControllers();
         services.AddApiVersioning(x =>
         {
             x.DefaultApiVersion = new ApiVersion(1, 0);
             x.AssumeDefaultVersionWhenUnspecified = true;
             x.ReportApiVersions = true;
         });
         services.AddSwaggerGen(c =>
         {
             c.SwaggerDoc("v1", new OpenApiInfo { Title = "WebAPIService", Version = "v1" });
         });
     }
    
  3. 然后,我们可以使用以下方法对 Web API 进行版本控制:查询字符串、 URL 和 HTTP header.

    根据你的描述,你想通过URL设置版本,如果是这样,你可以添加如下路由属性:

     [ApiVersion("1.0")]
     [Route("api/{v:apiVersion}/todoV1")]
     [ApiController]
     public class TodoV1Controller : ControllerBase
     {
         //...
     }
    

然后,请求url如下:

更多详细信息,请参阅本文:API ASP.NET Core 中的版本控制