使用 Microsoft.AspNetCore.Mvc.Versioning、Swashbuckle.AspNetCore 和 MaptoApiVersion
Using Microsoft.AspNetCore.Mvc.Versioning, Swashbuckle.AspNetCore, and MaptoApiVersion
我在使用 MapToApiVersion
时遇到问题。从 http://localhost:5000/swagger 开始,1.0 文档和 2.0 文档正确呈现 swagger ui 并且相应的 swagger.json 文件可用。 3.0 文档无法呈现,swagger.json 文件似乎没有生成。
实际服务已经启动,运行所有 3 个版本都可以正常使用。如果我从邮递员那里点击它,我会得到我期望的回复。
这是 运行Mvc.Versioning 的 1.1.1-rc1 和 Swashbuckle.AspNetCore 的 1.0.0。下面是完整的 .csproj
完整代码位于 https://github.com/senften/AspNetCoreVersionedWebApi/tree/maptoapiversion
当我 运行 在 Visual Studio 代码中调试时,我没有看到任何错误或有任何异常。我是否搞砸了启动或声明,或者我只是 运行 进入了 shim 或 swashbuckle 中的错误?
using Microsoft.AspNetCore.Mvc;
using VersionedWebApi.Model;
namespace VersionedWebApi.Controllers
{
/// <summary>
/// GoodByeController, just saying Goodbye!
/// </summary>
[ApiVersion("1.0", Deprecated = true)]
[ApiVersion("3.0")]
[Route("api/v{api-version:apiVersion}/[controller]")]
public class GoodByeController : Controller
{
/// <summary>
/// Default Get call returning Goodbye world!
/// </summary>
/// <returns></returns>
[HttpGet]
[ProducesResponseType(typeof(GoodByeWorldModel), 200)]
[ProducesResponseType(typeof(void), 404)]
public GoodByeWorldModel Get()
{
return new GoodByeWorldModel();
}
/// <summary>
/// Default Get call returning Goodbye world!
/// </summary>
/// <returns></returns>
[HttpGet, MapToApiVersion("3.0")]
[ProducesResponseType(typeof(VersionedWebApi.Model.v3.GoodByeWorldModel), 200)]
[ProducesResponseType(typeof(void), 404)]
public VersionedWebApi.Model.v3.GoodByeWorldModel GetV3()
{
return new VersionedWebApi.Model.v3.GoodByeWorldModel();
}
}
}
startup.cs
using System.Xml.XPath;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using SwashbuckleAspNetVersioningShim;
namespace VersionedWebApi
{
public class Startup
{
public Startup()
{
}
public IConfigurationRoot Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
var mvcBuilder = services.AddMvc();
services.AddMvcCore().AddVersionedApiExplorer();
// Adds versioning capabilities, defaulting to version 1.0 calls if available
services.AddApiVersioning(o =>
{
o.AssumeDefaultVersionWhenUnspecified = true;
o.DefaultApiVersion = new ApiVersion(1, 0);
});
// Add generated documentation
services.AddSwaggerGen(c =>
{
var provider = services.BuildServiceProvider().GetRequiredService<IApiVersionDescriptionProvider>();
SwaggerVersioner.ConfigureSwaggerVersions(c, provider);
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, ApplicationPartManager partManager, IApiVersionDescriptionProvider provider)
{
// Generate swagger.json
app.UseSwagger();
// Let's enable SwaggerUI
app.UseSwaggerUI(c =>
{
SwaggerVersioner.ConfigureSwaggerVersions(c, provider);
});
app.UseMvc();
// This is new for v1.1 and is a behavioral breaking change from previous (including 1.1-beta)
// See the release notes: https://github.com/Microsoft/aspnet-api-versioning/releases/tag/v1.1-rc1
app.UseApiVersioning();
}
}
}
csproj 文件
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp1.1</TargetFramework>
<Company />
<Description>A .NET Core Web API project demonstrating versioning a Web API and generating interactive documentation with Swagger.</Description>
<RepositoryUrl>https://github.com/senften/AspNetCoreVersionedWebApi</RepositoryUrl>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DocumentationFile></DocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore" Version="1.1.2" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.3" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="1.1.0-rc1"/>
<PackageReference Include="Swashbuckle.AspNetCore" Version="1.0.0" />
<PackageReference Include="SwashbuckleAspNetVersioningShim" Version="1.0.0-beta4"/>
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0.0-msbuild3-final" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="1.0.0"/>
<DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="*"/>
</ItemGroup>
</Project>
需要对您的代码进行几处更改。
1) 将下面的代码更改为
[ApiVersion("3.0"), Route("api/v{api-version:apiVersion}/[controller]")]
[Route("api/v{api-version:apiVersion}/[controller]")]
public class HelloController : Controller
{ }
[ApiVersion("3.0"), Route("api/v{api-version:apiVersion}/[controller]")]
public class HelloController : Controller
{ }
2) 添加 MapToApiVersion 1.0 以避免冲突
[HttpGet, MapToApiVersion("1.0")]
[ProducesResponseType(typeof(GoodByeWorldModel), 200)]
[ProducesResponseType(typeof(void), 404)]
public GoodByeWorldModel Get()
{
return new GoodByeWorldModel();
}
您 运行 遇到的问题是 shim 库的行为。
生成 Swagger 文档后,控制器上指定的 ApiVersion
将应用于其中未明确设置为其他内容的所有方法。
在这种情况下,因为 Get()
方法上没有 MapToApiVersion
属性,所以它被添加到 V1 和 V3 Swagger 文档中,因为这是在控制器上指定的。这会在生成 Swagger 文档时导致过载错误。
好消息是这是一个简单的修复,只需将 [HttpGet, MapToApiVersion("1.0")]
添加到您的 Get()
方法中,它看起来像这样
/// <summary>
/// Default Get call returning Goodbye world!
/// </summary>
/// <returns></returns>
[HttpGet, MapToApiVersion("1.0")]
[ProducesResponseType(typeof(GoodByeWorldModel), 200)]
[ProducesResponseType(typeof(void), 404)]
public GoodByeWorldModel Get()
{
return new GoodByeWorldModel();
}
Get()
方法只会被添加到 V1 文档中,您的代码的其余部分可以保持原样。
在 GitHub Readme 上有关于 Shim
的更多详细信息
我在使用 MapToApiVersion
时遇到问题。从 http://localhost:5000/swagger 开始,1.0 文档和 2.0 文档正确呈现 swagger ui 并且相应的 swagger.json 文件可用。 3.0 文档无法呈现,swagger.json 文件似乎没有生成。
实际服务已经启动,运行所有 3 个版本都可以正常使用。如果我从邮递员那里点击它,我会得到我期望的回复。
这是 运行Mvc.Versioning 的 1.1.1-rc1 和 Swashbuckle.AspNetCore 的 1.0.0。下面是完整的 .csproj
完整代码位于 https://github.com/senften/AspNetCoreVersionedWebApi/tree/maptoapiversion
当我 运行 在 Visual Studio 代码中调试时,我没有看到任何错误或有任何异常。我是否搞砸了启动或声明,或者我只是 运行 进入了 shim 或 swashbuckle 中的错误?
using Microsoft.AspNetCore.Mvc;
using VersionedWebApi.Model;
namespace VersionedWebApi.Controllers
{
/// <summary>
/// GoodByeController, just saying Goodbye!
/// </summary>
[ApiVersion("1.0", Deprecated = true)]
[ApiVersion("3.0")]
[Route("api/v{api-version:apiVersion}/[controller]")]
public class GoodByeController : Controller
{
/// <summary>
/// Default Get call returning Goodbye world!
/// </summary>
/// <returns></returns>
[HttpGet]
[ProducesResponseType(typeof(GoodByeWorldModel), 200)]
[ProducesResponseType(typeof(void), 404)]
public GoodByeWorldModel Get()
{
return new GoodByeWorldModel();
}
/// <summary>
/// Default Get call returning Goodbye world!
/// </summary>
/// <returns></returns>
[HttpGet, MapToApiVersion("3.0")]
[ProducesResponseType(typeof(VersionedWebApi.Model.v3.GoodByeWorldModel), 200)]
[ProducesResponseType(typeof(void), 404)]
public VersionedWebApi.Model.v3.GoodByeWorldModel GetV3()
{
return new VersionedWebApi.Model.v3.GoodByeWorldModel();
}
}
}
startup.cs
using System.Xml.XPath;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using SwashbuckleAspNetVersioningShim;
namespace VersionedWebApi
{
public class Startup
{
public Startup()
{
}
public IConfigurationRoot Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
var mvcBuilder = services.AddMvc();
services.AddMvcCore().AddVersionedApiExplorer();
// Adds versioning capabilities, defaulting to version 1.0 calls if available
services.AddApiVersioning(o =>
{
o.AssumeDefaultVersionWhenUnspecified = true;
o.DefaultApiVersion = new ApiVersion(1, 0);
});
// Add generated documentation
services.AddSwaggerGen(c =>
{
var provider = services.BuildServiceProvider().GetRequiredService<IApiVersionDescriptionProvider>();
SwaggerVersioner.ConfigureSwaggerVersions(c, provider);
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, ApplicationPartManager partManager, IApiVersionDescriptionProvider provider)
{
// Generate swagger.json
app.UseSwagger();
// Let's enable SwaggerUI
app.UseSwaggerUI(c =>
{
SwaggerVersioner.ConfigureSwaggerVersions(c, provider);
});
app.UseMvc();
// This is new for v1.1 and is a behavioral breaking change from previous (including 1.1-beta)
// See the release notes: https://github.com/Microsoft/aspnet-api-versioning/releases/tag/v1.1-rc1
app.UseApiVersioning();
}
}
}
csproj 文件
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp1.1</TargetFramework>
<Company />
<Description>A .NET Core Web API project demonstrating versioning a Web API and generating interactive documentation with Swagger.</Description>
<RepositoryUrl>https://github.com/senften/AspNetCoreVersionedWebApi</RepositoryUrl>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DocumentationFile></DocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore" Version="1.1.2" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.3" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="1.1.0-rc1"/>
<PackageReference Include="Swashbuckle.AspNetCore" Version="1.0.0" />
<PackageReference Include="SwashbuckleAspNetVersioningShim" Version="1.0.0-beta4"/>
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0.0-msbuild3-final" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="1.0.0"/>
<DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="*"/>
</ItemGroup>
</Project>
需要对您的代码进行几处更改。
1) 将下面的代码更改为
[ApiVersion("3.0"), Route("api/v{api-version:apiVersion}/[controller]")]
[Route("api/v{api-version:apiVersion}/[controller]")]
public class HelloController : Controller
{ }
[ApiVersion("3.0"), Route("api/v{api-version:apiVersion}/[controller]")]
public class HelloController : Controller
{ }
2) 添加 MapToApiVersion 1.0 以避免冲突
[HttpGet, MapToApiVersion("1.0")]
[ProducesResponseType(typeof(GoodByeWorldModel), 200)]
[ProducesResponseType(typeof(void), 404)]
public GoodByeWorldModel Get()
{
return new GoodByeWorldModel();
}
您 运行 遇到的问题是 shim 库的行为。
生成 Swagger 文档后,控制器上指定的 ApiVersion
将应用于其中未明确设置为其他内容的所有方法。
在这种情况下,因为 Get()
方法上没有 MapToApiVersion
属性,所以它被添加到 V1 和 V3 Swagger 文档中,因为这是在控制器上指定的。这会在生成 Swagger 文档时导致过载错误。
好消息是这是一个简单的修复,只需将 [HttpGet, MapToApiVersion("1.0")]
添加到您的 Get()
方法中,它看起来像这样
/// <summary>
/// Default Get call returning Goodbye world!
/// </summary>
/// <returns></returns>
[HttpGet, MapToApiVersion("1.0")]
[ProducesResponseType(typeof(GoodByeWorldModel), 200)]
[ProducesResponseType(typeof(void), 404)]
public GoodByeWorldModel Get()
{
return new GoodByeWorldModel();
}
Get()
方法只会被添加到 V1 文档中,您的代码的其余部分可以保持原样。
在 GitHub Readme 上有关于 Shim
的更多详细信息