gpt4 book ai didi

c# - Swagger 无法与多个版本的 ASP.NET WebApi 应用程序一起正常工作

转载 作者:太空狗 更新时间:2023-10-29 17:56:51 24 4
gpt4 key购买 nike

请帮我解决这个问题,一开始看起来很容易,现在我的项目迟到了:

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

相反,Swagger 无法为两个版本提供服务。在调试时,我注意到当在 SwaggerConfig.cs 中调用 c.MultipleApiVersions(...) 时,apiDesc.ActionDescriptor.ControllerDescriptor 报告的 Controller 始终是 PingController 而不是 Ping11Controller

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

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

谢谢!

调用 API v1.0 有效: enter image description here

也可以调用 API v1.1: enter image description here

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 的 Controller (位于同一命名空间中)

[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 资源管理器(请注意,由于初始化问题,我不得不将代码从 SwaggerConfig.cs 移至 WebApiConfig.cs):

        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);
    });

关于c# - Swagger 无法与多个版本的 ASP.NET WebApi 应用程序一起正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46058930/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com