【问题标题】:How to configure MultipleApiVersions in Swashbuckle using aspnet ApiVersioning如何使用 aspnet ApiVersioning 在 Swashbuckle 中配置 MultipleApiVersions
【发布时间】:2017-11-06 15:51:52
【问题描述】:

如何配置 swashbuckle 以使用 Aspnet API 验证? https://github.com/Microsoft/aspnet-api-versioning

在我的Startup.cs 中,我有以下代码来初始化基于属性的路由、api 版本控制和 swagger。

var constraintResolver = new DefaultInlineConstraintResolver()
{
    ConstraintMap =
    {
        ["apiVersion"] = typeof( ApiVersionRouteConstraint )
    }
};
config.MapHttpAttributeRoutes(constraintResolver);
config.AddApiVersioning();

config.EnableSwagger(c =>
{
    c.MultipleApiVersions(
        (apiDesc, targetApiVersion) => ResolveVersionSupportByRouteConstraint(apiDesc, targetApiVersion),
        (vc) =>
        {
            vc.Version("v1", "Swashbuckle Dummy API V1");
            vc.Version("v2", "Swashbuckle Dummy API V2");
        });
}



public static bool ResolveVersionSupportByRouteConstraint(ApiDescription apiDesc, string targetApiVersion)
{
    var versionConstraint = (apiDesc.Route.Constraints.ContainsKey("apiVersion"))
        ? apiDesc.Route.Constraints["apiVersion"] as RegexRouteConstraint
        : null;

    return (versionConstraint == null)
        ? false
        : versionConstraint.Pattern.Split('|').Contains(targetApiVersion);
}

当 ResolveVersionSupportByRouteConstraint 方法触发时,路由模板包含文字 api 字符串“api/v{version}/users” 我的用户控制器装饰有 [ApiVersion("1.0")] 并且我定义了以下路由 [Route(" api/v{版本:apiVersion}/users")]。当我用邮递员点击 api/v1/users 时,呼叫有效,但我不知道如何使用 Swashbuckle/Swagger 进行此操作。

我希望我的 swagger 文档看起来像 asp.net 核心 api 样板的示例,除了我使用 Owin 和 owin 启动类而不是 .net 核心:https://github.com/ASP-NET-Core-Boilerplate/Templates/blob/master/MVC%206%20API.md

【问题讨论】:

    标签: c# asp.net-web-api swagger swashbuckle


    【解决方案1】:

    你可以找到例子here 这就是我在启动自托管 owin 应用程序时的做法:

    public void Configuration(IAppBuilder appBuilder)
        {
            HttpConfiguration config = new HttpConfiguration();
            //configure your app
    
            config.AddApiVersioning(o =>
            {
                o.ReportApiVersions = true;
                o.ApiVersionReader = new UrlSegmentApiVersionReader();
            });
            var constraintResolver = new DefaultInlineConstraintResolver()
            {
                ConstraintMap = { ["apiVersion"] = typeof(ApiVersionRouteConstraint) }
            };
            config.MapHttpAttributeRoutes(constraintResolver);
            SwaggerConfiguration.Configure(config);            
            appBuilder.UseWebApi(config);
        }
    

    swagger 的配置非常简单,主要部分在这里 VersionedApiExplorer(确保你传递了正确的 api 的 groupnameformat,我的格式是 v1、v2 等):

    public static class SwaggerConfiguration
    {       
        public static void Configure(HttpConfiguration config)
        {
            var apiExplorer = config.AddVersionedApiExplorer(o => o.GroupNameFormat = "'v'V");
            config.EnableSwagger(
                    swagger =>
                    {
                        swagger.MultipleApiVersions(
                            (apiDesc, targetApiVersion) => apiDesc.GetGroupName() == targetApiVersion,
                            versionBuilder =>
                            {
                                foreach (var group in apiExplorer.ApiDescriptions)
                                {
                                    var description = "";
                                    if (group.IsDeprecated) description += "This API deprecated";
    
                                    versionBuilder.Version(group.Name, $"Service API {group.ApiVersion}")
                                        .Description(description);
                                }
                            });
                        swagger.DocumentFilter<VersionFilter>();
                        swagger.OperationFilter<VersionOperationFilter>();
                    })
                .EnableSwaggerUi(cfg => cfg.EnableDiscoveryUrlSelector());
        }
    

    在控制器中添加属性 ApiVersion 和 RoutePrefix

    [ApiVersion("1")]
    [RoutePrefix("api/v{version:apiVersion}/history")]
    public class HistoryController: ApiController
    

    如果您对 VersionFilter 和 VersionOperationFilter 感到困惑,这里有代码。此过滤器会在 swagger 中修改生成的路由和参数(没有您的路由看起来像 /v{version}/{actionName} 并包含所需的参数版本)

    public class VersionFilter : IDocumentFilter
    {
        public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
        {
            swaggerDoc.paths = swaggerDoc.paths
                .ToDictionary(
                    path => path.Key.Replace("v{version}", swaggerDoc.info.version),
                    path => path.Value
                );
        }
    }
    public class VersionOperationFilter : IOperationFilter
    {
        public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
        {
            var version = operation.parameters?.FirstOrDefault(p => p.name == "version");
            if (version != null)
            {
                operation.parameters.Remove(version);
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      我认为 ResolveVersionSupportByRouteConstraint 方法可能是错误的,请参阅:https://github.com/domaindrivendev/Swashbuckle/issues/197#issuecomment-75288894

      【讨论】:

        猜你喜欢
        • 2021-10-31
        • 1970-01-01
        • 2020-10-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-17
        相关资源
        最近更新 更多