ApiVersion 属性在 .NET 8 中不起作用

ApiVersion attribute not working in .NET 8

提问人:Lee Z 提问时间:11/17/2023 最后编辑:Guru StronLee Z 更新时间:11/22/2023 访问量:80

问:

我最近将我的 webapi 升级到 .NET 8。当我测试我的控制器时,ApiVersion 属性在 swagger 页面中不起作用。

[ApiVersion("1.0")]
[Route("v{version:apiVersion}/api/[controller]")]
[ApiController]
[Authorize]
public class SubscriptionController(ISubscriptionDataService subscriptionDataService, 
                                    IConfigurationService configurationService) : ControllerBase

在 swagger 页面中,默认情况下不会像在 .NET 7 中那样填充版本。

enter image description here

以前,使用默认模板 weatherforecast 控制器时,默认情况下会填充该行为。

该控制器的代码如下所示。

[ApiVersion("1.0")]
[Route("v{version:apiVersion}/api/[controller]")]
[ApiController]
[Authorize]
public class WeatherForecastController : ControllerBase

enter image description here

在 Program.cs 中,添加了以下内容以执行版本控制。

private static void AddApiVersioning(IServiceCollection services)
{
    services.AddApiVersioning(options =>
    {
        options.AssumeDefaultVersionWhenUnspecified = false;
        options.ReportApiVersions = false;
    });

    services.AddVersionedApiExplorer(options =>
    {
        options.GroupNameFormat = "'v'VVV";
        options.SubstituteApiVersionInUrl = true;
    });
}

编辑 1

由于以下弃用,需要更改执行此操作的方式。

Microsoft.AspNetCore.Mvc.Versioning -> Asp.Versioning.Mvc Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer -> Asp.Versioning.Mvc.ApiExplore

在 Program.cs 中,需要执行以下操作:

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.Services.AddApiVersioning(options =>
{
    options.DefaultApiVersion = new ApiVersion(1, 0);
    options.AssumeDefaultVersionWhenUnspecified = false;
    options.ReportApiVersions = false;
}).AddApiExplorer(options =>
{
    options.GroupNameFormat = "'v'VVV";
    options.SubstituteApiVersionInUrl=true;
});


var app = builder.build();

app.UseSwagger();
app.UseSwaggerUI(options =>
{
    var descriptions = app.DescribeApiVersions();
    foreach (var description in descriptions)
    {
        var url = $"/swagger/{description.GroupName}/swagger.json";
        var name = description.GroupName.ToUpperInvariant();
        options.SwaggerEndpoint(url, name);
    }
});

在控制器中,应将 [ApiVersion(“1.0”)] 属性替换为 [Asp.Versioning.ApiVersion(“1.0”)]。

这在生成的 Microsoft webapi 模板中有效,但如果使用其他 swagger 属性并具有其他中间件,则仍然失败(即必须输入版本)。

编辑 2

经过大量实验,即使在 Microsoft 测试项目中,类级别和方法级别的多个路由似乎也不再有效。

不在 Swagger 中工作

using Microsoft.AspNetCore.Mvc;

namespace webapitest.Controllers;

[Asp.Versioning.ApiVersion("1.0")]
[Route("v{version:apiVersion}/api/[controller]")]
[ApiController]
public class WeatherForecastController : ControllerBase
{
    private static readonly string[] Summaries = new[]
    {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

    [HttpGet]
    [Route(("/Weather"))]
    public IEnumerable<WeatherForecast> Get()
    {
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
    }
}

在 Swagger 中工作

using Microsoft.AspNetCore.Mvc;

namespace webapitest.Controllers;

[Asp.Versioning.ApiVersion("1.0")]
[ApiController]
public class WeatherForecastController : ControllerBase
{
    private static readonly string[] Summaries = new[]
    {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

    [HttpGet]
    [Route(("v{version:apiVersion}/api/[controller]/Weather"))]
    public IEnumerable<WeatherForecast> Get()
    {
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
    }
}

有谁能理解为什么这些不再起作用?

C# asp.net-routing net-8.0

评论

0赞 Lee Z 11/17/2023
这与弃用 Microsoft.AspNetCore.Mvc.Versioning 替换为 Asp.Versioning.Mvc 以及弃用 Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer 替换为 Asp.Versioning.Mvc.ApiExplorer 有关
0赞 Guru Stron 11/18/2023
那么哪一个是预期的呢?第二个?
0赞 Lee Z 11/18/2023
@GuruStron 请参阅上面的编辑 1。这解决了部分问题,并且是使用 youtube.com/watch?v=8Asq7ymF1R8 上的 Nick Chapsas 视频“在 .NET 中实现现代 API 版本控制”获得的。不过,该视频已过时,因为某些代码行在 .NET 8 中不起作用。
0赞 TylerH 12/15/2023
你的问题不清楚。您的编辑是否解决了原始问题?如果是这样,它们需要作为答案发布,而不是作为对问题的编辑。

答:

2赞 Denis Micheal 12/11/2023 #1

对于仍然面临与此类似的问题的其他任何人.提供 Net8 支持

只需将您的软件包更新到版本Asp.Versioning8.0.0