C# 使用多个端点从Swagger对文档进行RESTful api版本控制和分组

C# 使用多个端点从Swagger对文档进行RESTful api版本控制和分组,c#,asp.net-core-mvc,swagger,asp.net-core-webapi,api-versioning,C#,Asp.net Core Mvc,Swagger,Asp.net Core Webapi,Api Versioning,我试图在一个有API端点的MVC dotnet核心应用程序上实现版本选项 我想要的是这样的安排 --AiM api |_v1 |_v2 --RMS api |_v1 我让它大部分工作,但v1上的项目没有显示在v2上。输出是这样的 但是当我们在AiM v2端点上看到版本2时,我只看到了一项 这不是我所期望的 我做了一个测试,让每一个都像这样大摇大摆地显示在不同的页面上 --AiM api |_v1 |_v2 --RMS api |_v1 内部控

我试图在一个有API端点的MVC dotnet核心应用程序上实现版本选项

我想要的是这样的安排

 --AiM api
   |_v1
   |_v2
 --RMS api
   |_v1
我让它大部分工作,但v1上的项目没有显示在v2上。输出是这样的

但是当我们在AiM v2端点上看到版本2时,我只看到了一项

这不是我所期望的

我做了一个测试,让每一个都像这样大摇大摆地显示在不同的页面上

 --AiM api
   |_v1
   |_v2
 --RMS api
   |_v1
内部控制器

在Startup.cs中

在index.html中,对于swagger ui文档模板文件

<script type="text/javascript">
    window.JSConfig = JSON.parse('{"SwaggerEndpoints":[{"Url":"/doc/aim_v1/scheme.json","Description":"AiM v1.0.0"},{"Url":"/doc/aim_v2/scheme.json","Description":"AiM v2.0.0"},{"Url":"/doc/rms_v1/scheme.json","Description":"RMS v1.0.0"}],"BooleanValues":["false","true"],"DocExpansion":"list","SupportedSubmitMethods":["get","post","put","delete","patch"],"OnCompleteScripts":[],"OnFailureScripts":[],"ShowRequestHeaders":false,"JsonEditor":false,"OAuth2ClientId":"your-client-id","OAuth2ClientSecret":"your-client-secret-if-required","OAuth2Realm":"your-realms","OAuth2AppName":"your-app-name","OAuth2ScopeSeparator":" ","OAuth2AdditionalQueryStringParams":{}}');

$(function () {

  hljs.configure({
    highlightSizeThreshold: 5000
  });

  // Pre load translate...
  if(window.SwaggerTranslator) {
    window.SwaggerTranslator.translate();
  }
  window.swaggerUi = new SwaggerUi({
      url: "/doc/aim_v1/scheme.json",
    dom_id: "swagger-ui-container",
    supportedSubmitMethods: ['get', 'post'],
    onComplete: function(swaggerApi, swaggerUi){
      if(typeof initOAuth == "function") {
        initOAuth({
            clientId: "ffff==",
            clientSecret: "bbbb",
            realm: "wsu-api",
            appName: "wsu-api-broker",
            scopeSeparator: " ",
            additionalQueryStringParams: {}
        });
      }

      if(window.SwaggerTranslator) {
        window.SwaggerTranslator.translate();
      }
      _.each(JSConfig.OnCompleteScripts, function (script) {
          $.getScript(script);
      });

    },
    onFailure: function(data) {
      log("Unable to Load SwaggerUI");
    },
    docExpansion: false,
    jsonEditor: false,
    defaultModelRendering: 'schema',
    showRequestHeaders: false
  });

  window.swaggerUi.load();

  function log() {
    if ('console' in window) {
      console.log.apply(console, arguments);
    }
  }
});


为了获得不同端点上的项目,我在类上使用了[ApiExplorerSettingsGroupName=aim_v1],并在Startup.cs和index.html文件中匹配它们。此时,我不确定在何处进行编辑,以获取[ApiVersion2.0]上显示的所有[ApiVersion1.0]项,因为我认为ApiExplorerSettings组名就是它锁定的内容

要顺利集成所有内容,还需要添加API版本控制的官方软件包。这将以斯威格能够理解的方式为您整理所有API版本信息。官方的虚张声势/虚张声势的集成有额外的细节和示例

设置将如下所示:

public void ConfigureServices( IServiceCollection services )
{
    // 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
    services.AddMvcCore().AddVersionedApiExplorer(
        options =>
        {
            options.GroupNameFormat = "'v'VVV";
            options.SubstituteApiVersionInUrl = true;
        } );

    services.AddMvc();
    services.AddApiVersioning();
    services.AddSwaggerGen(
        options =>
        {
            var provider = services.BuildServiceProvider().GetRequiredService<IApiVersionDescriptionProvider>();

            foreach ( var description in provider.ApiVersionDescriptions )
            {
                options.SwaggerDoc( description.GroupName, CreateInfoForApiVersion( description ) );
            }

            options.IncludeXmlComments( XmlCommentsFilePath );
        } );
}

public void Configure( IApplicationBuilder app, IHostingEnvironment env, IApiVersionDescriptionProvider provider )
{
    app.UseMvc();
    app.UseSwagger();
    app.UseSwaggerUI(
        options =>
        {
            foreach ( var description in provider.ApiVersionDescriptions )
            {
                options.SwaggerEndpoint( $"/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant() );
            }
        } );
}

static string XmlCommentsFilePath
{
    get
    {
        var basePath = PlatformServices.Default.Application.ApplicationBasePath;
        var fileName = typeof( Startup ).GetTypeInfo().Assembly.GetName().Name + ".xml";
        return Path.Combine( basePath, fileName );
    }
}

static Info CreateInfoForApiVersion( ApiVersionDescription description )
{
    var info = new Info()
    {
        Title = $"Sample API {description.ApiVersion}",
        Version = description.ApiVersion.ToString(),
        Description = "A sample application with Swagger, Swashbuckle, and API versioning.",
        Contact = new Contact() { Name = "Bill Mei", Email = "bill.mei@somewhere.com" },
        TermsOfService = "Shareware",
        License = new License() { Name = "MIT", Url = "https://opensource.org/licenses/MIT" }
    };

    if ( description.IsDeprecated )
    {
        info.Description += " This API version has been deprecated.";
    }

    return info;
}

这个问题有一个完整的工作答案:


正如作者所说,ConfigureServices中AddSwagger Gen中的DocInclusionPredicate正在将适当的控制器映射到所需的swagger文件。

可能重复的@NarottamGoyal您的意思是可能的重复。。日期很重要lol…我的坏消息删除了重复标志。我有一个与这些代码片段非常相似的方法。问题是ApiVersionDescription.GroupName始终为v1或v2,但不包含在中定义的GroupNameApiExplorerSettings@EricBDev,在API版本控制5.0+中,如果显式设置了ApiExplorerSettingsAttribute.GroupName,则将使用它。但是,您应该注意,这将所有分组的责任都推到了您身上。唯一合理的分组方式是按API版本或您显式配置的任何内容进行分组。任何其他方法都可能最适合自定义IApiDescriptionProvider,它可以按照您想要的方式整理内容。尽管使用.net core 3.1,我最终还是在这个问题上找到了合适的解决方案:免责声明:我是API版本控制的作者是的,这种方法可以工作,但我仍然建议使用自定义IApiDescriptionProvider。这是一个更简单的解决方案。这就是API版本控制首先整理事情的方式。我已经为参考问题提供了另一个答案,该问题演示了如何创建自定义IApiDescriptionProvider。当Swashback发生更改、您更改OpenAPI文档生成器或需要在另一个上下文(例如:测试自动化)中使用信息时,它还可以继续工作。
public void ConfigureServices( IServiceCollection services )
{
    // 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
    services.AddMvcCore().AddVersionedApiExplorer(
        options =>
        {
            options.GroupNameFormat = "'v'VVV";
            options.SubstituteApiVersionInUrl = true;
        } );

    services.AddMvc();
    services.AddApiVersioning();
    services.AddSwaggerGen(
        options =>
        {
            var provider = services.BuildServiceProvider().GetRequiredService<IApiVersionDescriptionProvider>();

            foreach ( var description in provider.ApiVersionDescriptions )
            {
                options.SwaggerDoc( description.GroupName, CreateInfoForApiVersion( description ) );
            }

            options.IncludeXmlComments( XmlCommentsFilePath );
        } );
}

public void Configure( IApplicationBuilder app, IHostingEnvironment env, IApiVersionDescriptionProvider provider )
{
    app.UseMvc();
    app.UseSwagger();
    app.UseSwaggerUI(
        options =>
        {
            foreach ( var description in provider.ApiVersionDescriptions )
            {
                options.SwaggerEndpoint( $"/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant() );
            }
        } );
}

static string XmlCommentsFilePath
{
    get
    {
        var basePath = PlatformServices.Default.Application.ApplicationBasePath;
        var fileName = typeof( Startup ).GetTypeInfo().Assembly.GetName().Name + ".xml";
        return Path.Combine( basePath, fileName );
    }
}

static Info CreateInfoForApiVersion( ApiVersionDescription description )
{
    var info = new Info()
    {
        Title = $"Sample API {description.ApiVersion}",
        Version = description.ApiVersion.ToString(),
        Description = "A sample application with Swagger, Swashbuckle, and API versioning.",
        Contact = new Contact() { Name = "Bill Mei", Email = "bill.mei@somewhere.com" },
        TermsOfService = "Shareware",
        License = new License() { Name = "MIT", Url = "https://opensource.org/licenses/MIT" }
    };

    if ( description.IsDeprecated )
    {
        info.Description += " This API version has been deprecated.";
    }

    return info;
}