I have two Swagger docs generated by Swashbuckle, namely docs/v1 and docs/v2. However docs/v2 doesn't provide information on the action GetV2(). Please help if Swashbuckle has an option to address this.
1.Since the route template appears to be same for actions get() and getv2(), docs v2 doesn't show any info about getV2().
2. Swagger definition doesn't look v1.0/get while appears as v{version}/get in docs/v1
Note:I have refered on apiversioning samples, but not sure what am I missing. All samples refer to Swashbuckle.core while i use Swashbuckle.
[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");
}
}
This is my controller including two actions, one for version v1 and one for v2. Below is the webapi.config for the route constraint:
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://learn.microsoft.com/en-us/aspnet/web-api/overview/security/authentication-filters
config.SuppressHostPrincipal();
}
My Swagger config has the code:
[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;
}
}
}