Swagger无法与ASP.NET WebApi应用程序的多个版本一起正常使用 [英] Swagger not working correctly with multiple versions of ASP.NET WebApi app

查看:60
本文介绍了Swagger无法与ASP.NET WebApi应用程序的多个版本一起正常使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请帮助我,起初看起来很简单,现在我在项目中很晚:

Please help me with this, it looked easy at first, now I'm late in the project:

我正在尝试为Swagger设置ASP.NET WebApi项目的API版本控制.API版本控制工作正常,调用不同的版本会返回正确的结果(请参见下文).

I'm trying to setup API versioning for a ASP.NET WebApi project, along with Swagger. The API versioning works fine, calling different versions returns the correct results (see below).

相反,Swagger无法同时提供两个版本.调试时,我注意到在SwaggerConfig.cs中调用 c.MultipleApiVersions(...)时, apiDesc.ActionDescriptor.ControllerDescriptor 报告的控制器始终为PingController ,永远不要 Ping11Controller .

On the contrary, Swagger fails to serve both versions. While debugging, I noticed that when c.MultipleApiVersions(...) gets called in SwaggerConfig.cs, the controller reported by apiDesc.ActionDescriptor.ControllerDescriptor is always PingController and never Ping11Controller.

有人可以指出需要做些什么来解决这个问题,并且让Swagger也适用于这两个版本吗?

Can somebody point out what needs to be done to solve this and have Swagger also work for both versions?

下面,API版本的代码和证明可以正常工作,而Swagger仅适用于v1.0.

Below, the code and proof of API versioning working fine while Swagger working only for v1.0.

谢谢!

调用API v1.0可以:

调用API v1.1也可以:

Swagger for v1.0很好:( http://localhost:50884/v1.0/swagger )

{
   "swagger":"2.0",
   "info":{
      "version":"v1.0",
      "title":"My API v1.0"
   },
   "host":"localhost:50884",
   "schemes":[
      "http"
   ],
   "paths":{
      "/api/ping":{
         "get":{
            "tags":[
               "Ping"
            ],
            "summary":"Get a pong.",
            "operationId":"GetAPong",
            "consumes":[
            ],
            "produces":[
               "application/json",
               "text/json",
               "application/xml",
               "text/xml"
            ],
            "responses":{
               "200":{
                  "description":"OK"
               },
               "404":{
                  "description":"NotFound"
               }
            }
         }
      }
   },
   "definitions":{
   }
}

v1.1的Swagger为空:( http://localhost:50884/v1.1/swagger )

{
   "swagger":"2.0",
   "info":{
      "version":"v1.1",
      "title":"My API v1.1"
   },
   "host":"localhost:50884",
   "schemes":[
      "http"
   ],
   "paths":{
   },
   "definitions":{
   }
}

代码

App_Start \ WebApiConfig.cs:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.AddApiVersioning(options => {
            options.ReportApiVersions = true;
        });

        var constraintResolver = new System.Web.Http.Routing.DefaultInlineConstraintResolver();
        constraintResolver.ConstraintMap.Add("apiVersion", typeof(Microsoft.Web.Http.Routing.ApiVersionRouteConstraint));
        config.MapHttpAttributeRoutes(constraintResolver);

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

App_Start \ SwaggerConfig.cs:

public class SwaggerConfig
{
    static string XmlCommentsFilePath
    {
        get
        {
            var basePath = System.AppDomain.CurrentDomain.RelativeSearchPath;
            var fileName = typeof(SwaggerConfig).GetTypeInfo().Assembly.GetName().Name + ".xml";
            return Path.Combine(basePath, fileName);
        }
    }

    public static void Register()
    {
        var configuration = GlobalConfiguration.Configuration;
        GlobalConfiguration.Configuration.EnableSwagger("{apiVersion}/swagger", c => {
                c.OperationFilter<SwaggerDefaultValues>();
                c.MultipleApiVersions((System.Web.Http.Description.ApiDescription apiDesc, string targetApiVersion) =>
                {
                    var attr = apiDesc.ActionDescriptor.ControllerDescriptor.GetCustomAttributes<Microsoft.Web.Http.ApiVersionAttribute>().FirstOrDefault();
                    if (attr == null && (targetApiVersion == "v1" || targetApiVersion == "v1.0")) return true;
                    var match = (attr != null) && (attr.Versions.FirstOrDefault(v => "v" + v.ToString() == targetApiVersion) != null);
                    return match;
                },
                (vc) =>
                {
                    vc.Version("v1.1", "My API v1.1");
                    vc.Version("v1.0", "My API v1.0");
                });

                c.IncludeXmlComments(SwaggerConfig.XmlCommentsFilePath);
            })
            .EnableSwaggerUi(c => {
                c.DocExpansion(DocExpansion.List);
                c.EnableDiscoveryUrlSelector();
            });
    }
}

v1.0和v1.1的控制器(位于同一名称空间中)

[ApiVersion("1.0")]
[RoutePrefix("api")]
[ControllerName("Ping")]
public class PingController : ApiController
{
    [HttpGet]
    [Route("ping")]
    [SwaggerOperation("GetAPong")]
    [SwaggerResponse(HttpStatusCode.OK)]
    [SwaggerResponse(HttpStatusCode.NotFound)]
    public string Get()
    {
        return "Pong v1.0";
    }
}

[ApiVersion("1.1")]
[RoutePrefix("api")]
[ControllerName("Ping")]
public class Ping11Controller : ApiController
{
    [HttpGet]
    [Route("ping")]
    [SwaggerOperation("GetAPong")]
    [SwaggerResponse(HttpStatusCode.OK)]
    [SwaggerResponse(HttpStatusCode.NotFound)]
    public string Get()
    {
        return "Pong v1.1";
    }
}

包装

<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.AspNet.WebApi" version="5.2.3" targetFramework="net46" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net46" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net46" />
<package id="Microsoft.AspNet.WebApi.Versioning" version="2.1.0" targetFramework="net46" />
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net46" />
<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="1.0.7" targetFramework="net46" />
<package id="Microsoft.IdentityModel.Logging" version="1.1.4" targetFramework="net46" />
<package id="Microsoft.IdentityModel.Tokens" version="5.1.4" targetFramework="net46" />
<package id="Microsoft.Net.Compilers" version="2.3.2" targetFramework="net46" developmentDependency="true" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net46" />
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="net46" />
<package id="NLog" version="4.4.12" targetFramework="net46" />
<package id="Swashbuckle" version="5.6.0" targetFramework="net46" />
<package id="Swashbuckle.Core" version="5.6.0" targetFramework="net46" />
<package id="System.IdentityModel.Tokens.Jwt" version="5.1.4" targetFramework="net46" />
<package id="WebActivatorEx" version="2.2.0" targetFramework="net46" />
</packages>

推荐答案

通过以下方式解决它:

  1. 添加 Microsoft.AspNet.WebApi.Versioning.ApiExplorer 程序包
  2. 使用如下所示的版本化API资源管理器(请注意,由于初始化问题,我不得不从WebApiConfig.cs中的SwaggerConfig.cs中移动代码):

  1. Adding the Microsoft.AspNet.WebApi.Versioning.ApiExplorer package
  2. Using the versioned API explorer as below (note that I had to move the code from SwaggerConfig.cs in WebApiConfig.cs due to initialization issues):

    var apiExplorer = config.AddVersionedApiExplorer(options => {
        options.GroupNameFormat = "'v'VVV";
    });

    var versionSupportResolver = new Func<ApiDescription, string, bool>((apiDescription, version) => apiDescription.GetGroupName() == version);

    var versionInfoBuilder = new Action<VersionInfoBuilder>(info => {
        foreach (var group in apiExplorer.ApiDescriptions)
        {
            info.Version(group.Name, $"MyAPI v{group.ApiVersion}");
        }
    });

    config
        .EnableSwagger("{apiVersion}/swagger", swagger => {
            swagger.OperationFilter<SwaggerDefaultValues>();
            swagger.MultipleApiVersions(versionSupportResolver, versionInfoBuilder);
            swagger.IncludeXmlComments(WebApiConfig.XmlCommentsFilePath);
        })
        .EnableSwaggerUi(swaggerUi => {
            swaggerUi.EnableDiscoveryUrlSelector();
            swaggerUi.DocExpansion(DocExpansion.List);
        });

这篇关于Swagger无法与ASP.NET WebApi应用程序的多个版本一起正常使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆