提问人:Lee Z 提问时间:11/17/2023 最后编辑:Guru StronLee Z 更新时间:11/22/2023 访问量:80
ApiVersion 属性在 .NET 8 中不起作用
ApiVersion attribute not working in .NET 8
问:
我最近将我的 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 中那样填充版本。
以前,使用默认模板 weatherforecast 控制器时,默认情况下会填充该行为。
该控制器的代码如下所示。
[ApiVersion("1.0")]
[Route("v{version:apiVersion}/api/[controller]")]
[ApiController]
[Authorize]
public class WeatherForecastController : ControllerBase
在 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();
}
}
有谁能理解为什么这些不再起作用?
答:
评论