【问题标题】:Issue with Swagger Docs generated on api versioning support on a single controller在单个控制器上的 api 版本控制支持上生成的 Swagger Docs 的问题
【发布时间】:2017-11-30 04:57:21
【问题描述】:

我有两个由 Swashbuckle 生成的 Swagger 文档,即 docs/v1 和 docs/v2。但是 docs/v2 没有提供有关 GetV2() 操作的信息。如果 Swashbuckle 可以选择解决此问题,请提供帮助。

1. 由于动作 get() 和 getv2() 的路由模板似乎相同,因此 docs v2 不显示任何有关 getV2() 的信息。

2。 Swagger 定义看起来不像 v1.0/get,而在 docs/v1 中显示为 v{version}/get

注意:我参考了 apiversioning 示例,但不确定我缺少什么。当我使用 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;
        }
    }
}

【问题讨论】:

    标签: asp.net asp.net-web-api swagger swashbuckle api-versioning


    【解决方案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 );
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多