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(IEnumerable
1 apiDescriptions)\r\n at Swashbuckle.Swagger.SwaggerGenerator.CreatePathItem(IEnumerable
1 apiDescriptions, SchemaRegistry schemaRegistry) \r\n 在 Swashbuckle.Swagger.SwaggerGenerator.c__DisplayClass7.b__4(IGrouping2 group)\r\n at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable
1 source, Func2 keySelector, Func
2 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/byusername
和 api/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 不支持:带路径的多个操作的主要内容,如果未能解决你的问题,请参考以下文章
005.CI4框架CodeIgniter, 通过带路径的view视图访问