Swagger 2.0 不支持:带路径的多个操作

Posted

技术标签:

【中文标题】Swagger 2.0 不支持:带路径的多个操作【英文标题】:Not supported by Swagger 2.0: Multiple operations with path 【发布时间】:2017-01-28 20:07:27 【问题描述】:

我在 WebApi 2 应用程序中集成了 swagger。当应用程序具有单个控制器时,它可以正常工作。 当我在应用程序中添加第二个控制器时。我收到以下错误:

发生错误。","ExceptionMessage":"Swagger 2.0 不支持:路径为 'api/Credential' 和方法为 'GET' 的多个操作。请参阅配置设置 - \"ResolveConflictingActions\" 了解潜在的解决方法","ExceptionType":"System.NotSupportedException","StackTrace":" 在 Swashbuckle.Swagger.SwaggerGeneratorOptions.DefaultConflictingActionsResolver(IEnumerable1 apiDescriptions)\r\n at Swashbuckle.Swagger.SwaggerGenerator.CreatePathItem(IEnumerable1 apiDescriptions, SchemaRegistry schemaRegistry) \r\n 在 Swashbuckle.Swagger.SwaggerGenerator.c__DisplayClass7.b__4(IGrouping2 group)\r\n at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable1 source, Func2 keySelector, Func2 elementSelector, IEqualityComparer1 comparer)\r\n at Swashbuckle.Swagger.SwaggerGenerator.GetSwagger(String rootUrl, String apiVersion)\r\n at Swashbuckle.Application.SwaggerDocsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n at System.Net.Http.HttpMessageInvoker.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n at System.Web.Http.Dispatcher.HttpRoutingDispatcher.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n at System.Net.Http.DelegatingHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n at System.Web.Http.Cors.CorsMessageHandler.<SendAsync>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.HttpServer.d__0.MoveNext()" http://localhost:50950/swagger/docs/v1

在第二个控制器中,我添加了以下两种方法。

 string Get(string username, string password);

 string Get(string credential);

如果我评论其中一种方法。然后就可以正常使用了。

知道怎么解决吗?

【问题讨论】:

***.com/a/42976546/1335146 您可能想customize Swashbuckle。然后由您来调整过滤方法以达到您的需要。 【参考方案1】:

在文件 AppStart/SwaggerConfig.cs

第一个,必须导入Linq

using System.Linq;

并在同一个文件中添加这一行

c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());

就在里面:

GlobalConfiguration.Configuration 
                .EnableSwagger(c =>
                     ...

一个考虑: 在您的控制器中,您必须使用 Http methods

[HttpGet]
[Route("something")]
public List<model> something()....

[HttpGet]
[Route("something2")]
public List<model2> something2()....

[HttpPost]
[Route("mypost1")]
public List<model> mypost1()....

[HttpPost]
[Route("mypost2")]
public List<model2> mypost2()....

【讨论】:

这行得通,但重要的是要理解为什么:如果有两条匹配的路线,它只会记录第一个。有些人可能更喜欢更改方法路由名称。 答案中应该有一个警告。我会劝阻人们不要使用这种方法来解决这个错误。我宁愿更改路线名称。 @KishanVaishnav 该评论对这个问题没有任何好处。问题很清楚,答案也与问题相关。问题不是“是一个好方法”。请再次阅读问题并尝试提出建设性的建议 @MrMins 我很抱歉。我不明白您为什么要写有关更改 SwaggerConfig 的文章。改变路线还不够吗?【参考方案2】:

以上两种方法你有两种选择:

    将两种方法组合成一个具有三个参数的方法 - 每个方法都将在查询字符串中

    有单独的路由 URL,例如 - api/controller/byusernameapi/controller/bycredentials

【讨论】:

【参考方案3】:

我知道这是一个旧线程。我稍微偏离了 OP 问题。但是我最近遇到了这个问题,并花了很长时间试图弄清楚发生了什么(这个页面是谷歌的问题)。它可以帮助其他人摆脱数小时的痛苦。

我的控制器都扩展了一个基本控制器,我愚蠢地有一个公共功能而不是一个受保护的功能。所以大摇大摆地把公共功能当作复制品。

希望这可以帮助其他人避免花费不必要的时间。

【讨论】:

这是给我的。 Swagger 正在抛出 InvalidOperationException: The method 'get' on path '/Blog' is registered multiple times. 我有一个带有单个 public 方法的基本实体。 GetUserId()。将此方法更改为protected 为我解决了这个问题。由于错误消息,我确定这与我的多个 GET 方法有关,其中一个方法接受了字符串 id 参数,但不是 - 基类中的公共方法是它。【参考方案4】:

您可以在控制器上更改路线。

默认值为[Route("api/[controller]")]

你可以改成[Route("api/[controller]/[action]")]

【讨论】:

【参考方案5】:

我没见过的答案:我搞砸了 usings。

我的控制器有一些 MVC 项(列表项),因此有一个链接:

using System.Web.Http;
using System.Web.Mvc;

因此,不知何故,它被注册了两次(我假设)。问题已通过使用 RoutePrefix/Route/HttpGet 等的完整限定来解决。

namespace MyNameSpace

    [System.Web.Http.RoutePrefix("api/Reports")]
    public class ReportsController
    
        ...constructor...

        [System.Web.Http.Route("Scans")]
        [System.Web.Http.HttpGet,ResponseType(typeof(List<ReportClass>))]
        public ascyn Task<HttpResponseMessage> GetScans() ...

【讨论】:

【参考方案6】:

在使用属性路由的情况下也可能出现此问题。

如果属性路由与可路由的路由冲突,则会出现“多次操作”错误。

例子:

[HttpGet]
[SwaggerOperation("GetByUsername")]
[Route("[path]/User")]
public IHttpActionResult GetUser(string username)



更多关于属性路由的信息:https://docs.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2

【讨论】:

【参考方案7】:

在您的冲突方法上添加单独的路线。 比如[Route("GetByType")]在一个上面,[Route("GetById")]在另一个

【讨论】:

【参考方案8】:

对不起,我回答得太晚了:如果您有多个控制器,解决问题的方法是删除控制器上的任何路由版本控制属性;默认情况下,swagger 从 WebApiConfig 中选择路由。注意:您不需要提供操作名称或路由。只需确保没有两个动作具有相同的名称或签名;当然,它永远无法编译。

【讨论】:

【参考方案9】:

为方法[Route("ApiAnotherFunction")][HttpGet]添加路由属性。

【讨论】:

以上是关于Swagger 2.0 不支持:带路径的多个操作的主要内容,如果未能解决你的问题,请参考以下文章

java中如何创建带路径的文件

五CI框架之通过带路径的view视图路径访问

005.CI4框架CodeIgniter, 通过带路径的view视图访问

使用 swagger 4.x 包生成 swagger 2.0 yaml

Floyd最短路(带路径输出)

如何将 swagger 2.0 JSON 文件分解为多个模块