【问题标题】:How can I supply a path parameter to the displayed path in SwaggerUi?如何为 SwaggerUi 中显示的路径提供路径参数?
【发布时间】:2017-10-05 09:30:32
【问题描述】:

我在我的 WebAPI 项目上设置了 Swagger/Swashbuckle。我遵循了guide from Microsoft,其中介绍了如何使用 Swagger 设置 Aspnet.WebApi.Versioning。我的API有多个版本,所以在路由属性中设置了{version}参数,像这样:

[ApiVersion("2")]
[RoutePrefix("api/{version:apiVersion}/values")]
public class AccountController : ApiController
{
    [Route("UserInfo")]
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }
}

我的问题是,这会在文档中显示的路径中显示 {version} 属性,如下所示:

相反,我希望此路径属性实际上具有 ApiVersion 属性中的值,这样阅读文档的客户就不会感到困惑。理想情况下,假设 UrlDiscoverySelector 设置为 v2,上述路径应为:

/api/2/account/userinfo
/api/2/account/externallogin
/api/2/account/manageinfo

我尝试在 UI 中简单地替换 ApiExplorerRelativePath 中的 {version},但由于 {version} 已更改为 query 参数而不是 path,因此破坏了测试功能,这不是我的 API 的配置方式。

是否可以在 swagger 构建文档之前修改 ApiExplorer 中的值,同时仍保留测试功能?

【问题讨论】:

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


    【解决方案1】:

    用于 API 版本控制的 API Explorer 现在支持开箱即用的行为:

    options.SubstituteApiVersionInUrl = true
    

    这将为您完成替换工作,并从操作描述符中删除 API 版本参数。您通常不需要更改应用于替换值的默认格式,但您可以使用以下方法进行更改:

    options.SubstitutionFormat = "VVV"; // this is the default
    

    【讨论】:

      【解决方案2】:

      我正在使用 Swashbuckle 并使用了文档过滤器

      public class VersionedOperationsFilter : IDocumentFilter
      {
          public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
          {
              foreach (var apiDescriptionsGroup in context.ApiDescriptionsGroups.Items)
              {
                  var version = apiDescriptionsGroup.GroupName;
                  foreach (ApiDescription apiDescription in apiDescriptionsGroup.Items)
                  {
                      apiDescription.RelativePath = apiDescription.RelativePath.Replace("{version}", version);
                  }
              }
          }
      }
      

      并在 Startup.cs 的 ConfigureServices 方法中添加此过滤器:

      services.AddMvc();
              var defaultApiVer = new ApiVersion(1, 0);
      
      
              services.AddApiVersioning(option =>
              {
                  option.ReportApiVersions = true;
                  option.AssumeDefaultVersionWhenUnspecified = true;
                  option.DefaultApiVersion = defaultApiVer;
              });
      
              services.AddMvcCore().AddVersionedApiExplorer(e=>e.DefaultApiVersion = defaultApiVer);
      
              services.AddSwaggerGen(
                  options =>
                  {
                      var provider = services.BuildServiceProvider().GetRequiredService<IApiVersionDescriptionProvider>();
                      options.DocumentFilter<VersionedOperationsFilter>();
      
                      //// add a swagger document for each discovered API version
                      //// note: you might choose to skip or document deprecated API versions differently
                      foreach (var description in provider.ApiVersionDescriptions)
                      {
                              options.SwaggerDoc(description.GroupName.ToString(),
                                  CreateInfoForApiVersion(description));
                      }
      
                      //// integrate xml comments
                      options.IncludeXmlComments(Path.ChangeExtension(Assembly.GetEntryAssembly().Location, "xml"));
      
                  });
      

      end result in Swagger UI

      【讨论】:

      • 感谢您的回复,并为迟到的回复表示歉意,因为我才刚刚开始再次查看此内容。您的代码看起来很理想,但是您用于 IDocumentFilter 的签名与我正在使用的 Seashbuckle 版本不匹配。相反,它期望 Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer) - 请注意,我正在开发一个 WebApi 项目,而不是 MVC 项目,如果它有所作为
      • 问题是我使用的是 Swashbuckle.AspNetCore 版本,所以它有不同的签名,但原理应该是一样的——比如here
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-05
      • 1970-01-01
      • 1970-01-01
      • 2012-01-16
      • 1970-01-01
      相关资源
      最近更新 更多