我有两个由Swashbuckle生成的Swagger文档,即docs / v1和docs / v2。但是,docs / v2并未提供有关GetV2()操作的信息。如果Swashbuckle有解决此问题的选项,请提供帮助。
1.由于路径模板对于动作get()和getv2()似乎相同,因此docs v2不会显示有关getV2()的任何信息。
2。 Swagger定义看起来不像v1.0 / get,而在文档/ v1中显示为v {version} / get
注意:我已经提到了派送样品,但不确定我错过了什么。当我使用Swashbuckle时,所有样本都参考Swashbuckle.core。
[ApiVersion("1.0")]
[ApiVersion("2.0")]
public class HelloController : ApiControllerBase
{
[MapToApiVersion("1.0")]
[Route("v{version:apiVersion}/get")]
[HttpGet]
public ProjectSightActionResult Get()
{
return new Ok("Version 1.0");
}
[MapToApiVersion("2.0")]
[Route("v{version:apiVersion}/get")]
[HttpGet]
public ProjectSightActionResult GetV2()
{
return new Ok("Version 2.0");
}
}
这是我的控制器,包括两个动作,一个用于版本v1,另一个用于v2。以下是路径约束的webapi.config:
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Version Start
// https://github.com/Microsoft/aspnet-api-versioning/wiki/Versioning-via-the-URL-Path
// added to the web api configuration in the application setup
var constraintResolver = new DefaultInlineConstraintResolver()
{
ConstraintMap = {["apiVersion"] = typeof( ApiVersionRouteConstraint )}
};
config.MapHttpAttributeRoutes(constraintResolver);
config.AddApiVersioning();
// Version End
// Web API routes
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Filters.Add(new AuthenticationFilter());
// This causes Web API to remove the IPrincipal from any request that enters the Web API pipeline. Effectively, it "un-authenticates" the request.
// https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/authentication-filters
config.SuppressHostPrincipal();
}
我的Swagger配置包含代码:
[assembly: PreApplicationStartMethod(typeof(SwaggerConfig), "Register")]
namespace sample.WebAPI
{
public class SwaggerConfig
{
public static void Register()
{
var thisAssembly = typeof(SwaggerConfig).Assembly;
GlobalConfiguration.Configuration
.EnableSwagger(c =>
{
c.MultipleApiVersions(
(apiDesc, targetApiVersion) => ResolveVersionSupportByRouteConstraint(apiDesc, targetApiVersion),
vc =>
{
vc.Version("v1", "sample.WebAPI");
vc.Version("v2", "sample.WebAPI");
});
}
)
.EnableSwaggerUi(c =>
{
c.EnableDiscoveryUrlSelector();
// If your API supports ApiKey, you can override the default values.
// "apiKeyIn" can either be "query" or "header"
c.EnableApiKeySupport("x-jwt-assertion", "header");
});
}
private static string GetXmlCommentsPath()
{
return string.Format(@"{0}\bin\XmlComments.xml", AppDomain.CurrentDomain.BaseDirectory);
}
private static bool ResolveVersionSupportByRouteConstraint(ApiDescription apiDesc, string targetApiVersion)
{
//check for deprecated versions
var controllerVersionAttributes = apiDesc.ActionDescriptor.ControllerDescriptor.GetCustomAttributes<ApiVersionAttribute>(true);
if (!controllerVersionAttributes.Any())
{
return true; // include when no attributes are defined
}
if (targetApiVersion.StartsWith("v"))
{
targetApiVersion = targetApiVersion.Substring(1); // remove the leading "v" in `v{x.x}`
}
var apiVersion = ApiVersion.Parse(targetApiVersion);
var controllerApiVersion = controllerVersionAttributes
.Where(x => x.Versions.Contains(apiVersion))
.FirstOrDefault();
// has a compatible version, now check the action for [MapToApiVersion]
if (controllerApiVersion != null)
{
var actionMapToAttributes = apiDesc.ActionDescriptor.GetCustomAttributes<MapToApiVersionAttribute>(false);
if (!actionMapToAttributes.Any())
{
return true; // no MapTo attributes matched, then include the action
}
if (actionMapToAttributes.Any(x => x.Versions.Contains(apiVersion)))
{
return true; // include mapped action
}
}
return false;
}
}
}
答案 0 :(得分:1)
我不确定您是否曾解决过您的问题,但您现在可以使用官方API Explorer进行API版本控制,这使Swagger集成变得简单。您可以看到完整的工作示例here。
这是一个应该适合您的简略版本:
static void Register( HttpConfiguration configuration )
{
var constraintResolver = new DefaultInlineConstraintResolver() { ConstraintMap = { ["apiVersion"] = typeof( ApiVersionRouteConstraint ) } };
configuration.AddApiVersioning();
configuration.MapHttpAttributeRoutes( constraintResolver );
// note: this option is only necessary when versioning by url segment.
// the SubstitutionFormat property can be used to control the format of the API version
var apiExplorer = configuration.AddVersionedApiExplorer( options => options.SubstituteApiVersionInUrl = true );
configuration.EnableSwagger(
"{apiVersion}/swagger",
swagger =>
{
// build a swagger document and endpoint for each discovered API version
swagger.MultipleApiVersions(
( apiDescription, version ) => apiDescription.GetGroupName() == version,
info =>
{
foreach ( var group in apiExplorer.ApiDescriptions )
{
var description = "A sample application with Swagger, Swashbuckle, and API versioning.";
if ( group.IsDeprecated )
{
description += " This API version has been deprecated.";
}
info.Version( group.Name, $"Sample API {group.ApiVersion}" )
.Contact( c => c.Name( "Bill Mei" ).Email( "bill.mei@somewhere.com" ) )
.Description( description )
.License( l => l.Name( "MIT" ).Url( "https://opensource.org/licenses/MIT" ) )
.TermsOfService( "Shareware" );
}
} );
swagger.IncludeXmlComments( XmlCommentsFilePath );
} )
.EnableSwaggerUi( swagger => swagger.EnableDiscoveryUrlSelector() );
}
}
static string XmlCommentsFilePath
{
get
{
var basePath = System.AppDomain.CurrentDomain.RelativeSearchPath;
var fileName = typeof( Startup ).GetTypeInfo().Assembly.GetName().Name + ".xml";
return Path.Combine( basePath, fileName );
}
}