为啥我在发布 API 应用程序后收到“名为‘swagger_docs’的路由已在路由集合中”?

Posted

技术标签:

【中文标题】为啥我在发布 API 应用程序后收到“名为‘swagger_docs’的路由已在路由集合中”?【英文标题】:Why am I getting "A route named 'swagger_docs' is already in the route collection" after I publish my API App?为什么我在发布 API 应用程序后收到“名为‘swagger_docs’的路由已在路由集合中”? 【发布时间】:2015-06-08 23:43:15 【问题描述】:

发布我的 API 应用程序后,我收到了 ASP.NET 的黄色错误屏幕。错误消息显示“名为 'swagger_docs' 的路由已在路由集合中”。

我该如何解决这个问题?

【问题讨论】:

在我的情况下,这发生在重命名项目并重新编译之后。具有优先项目命名空间的项目的 DLL 仍在 BIN 中。从 bin 中删除所有内容并重新编译。 【参考方案1】:

这与 API 应用程序本身无关,而更多地与 Web API 相关。触发错误的原因很简单:

    您发布了基于 Web API 的 API 应用程序。 您放弃项目并开始开发基于 Web API 的新 API 应用程序 您希望发布新的 API 应用,而不是您在第 1 步创建的旧 API 应用。 您在“发布..”期间选择 API 应用程序,您将获得我们在第 1 步部署的现有 API 应用程序的发布配置文件。 您使用 Web Deploy 和发布配置文件进行部署,新 API 应用位于旧 API 应用之上。

这将触发我之前解释过的问题。发生这种情况是因为当您尝试启动应用程序时,Swashbuckle 注册了两条路由。一个旧的,一个新的。那是因为旧文件仍然存在于目的地。

要解决此问题,在 Web 部署期间,单击“设置”选项卡,然后展开“文件发布选项”。那里有一个复选框,名为“从目标中删除附加文件”。这将解决问题,因为它只会将您部署的文件保留在目标位置,而不会保留旧文件。

希望对你有帮助。

【讨论】:

尝试在本地调试应用时出现这种情况怎么办? 在单个解决方案中托管多个 WebAPI 时会发生此错误。正在寻找解决方案...【参考方案2】:

如果尝试在本地调试应用程序时发生这种情况怎么办? 这发生在我身上,原因是我重命名了我的程序集名称。所以 bin 文件夹有两个 dll 用于同一个项目,但名称不同,这导致了这个错误。一旦我删除了旧命名的 dll,一切都很好。希望这会有所帮助。

【讨论】:

这篇文章并不是回答问题的实际尝试。请注意*** doesn't work like a discussion forum,这是一个问答网站,每个帖子都是问题或问题的答案。帖子也可以有comments - 像这样的小句子 - 可用于批评或要求作者澄清。这应该是评论或new question【参考方案3】:

发生这种情况是因为您可能正在 WebApiConfig 类 SwaggerConfig 类中配置路由,如下所述:

WebApiConfig 文件:

public static class WebApiConfig

    public static void Register(HttpConfiguration config)
    
        SwaggerConfig.Register();
    

SwaggerConfig 文件:

using Swashbuckle.Application;

[assembly: PreApplicationStartMethod(typeof(SwaggerConfig), "Register")]

namespace NEOH.Api

    public class SwaggerConfig
    
        public static void Register()
        

您应该做的是删除 SwaggerConfig 文件上的程序集调用。

它应该可以工作。

【讨论】:

【参考方案4】:

我的解决方案和原因: 当我重命名 NamesSpaces、Refactored 等时,我遇到了同样的问题。 在阅读了其他人所做的之后,我尝试了:

在 Visual Studio 中清理了解决方案 手动清理 Bin 文件夹 检查了 Project Properties 中的命名空间(复制它以防万一)>> Build 选项卡>> 向下滚动到 Output 并确保XML 文档文件 是正确的。稍后您将需要此名称。 已打开:SwaggerConfig.cs >> 修复了此处的命名空间(复制、粘贴)c.SingleApiVersion("vX","NameSpace") 向下滚动直到找到:GetXmlCommentsPath() 复制并粘贴了 .xml 文件路径中的正确名称空间。 跑了,经过烟雾测试,完成了这篇文章。

【讨论】:

【参考方案5】:

我的问题是我引用了另一个具有 Swashbuckle 扩展的项目。 以下是我在不更改项目中引用的任何内容的情况下保留两个项目的方法:

    删除SwaggerConfig.cs下引用的项目创建的路由> Register就在GlobalConfiguration.Configuration.EnableSwagger(...).EnableSwaggerUi(...);之前:
// Clears the previous routes as this solution references another Swagger ASP.NET project which adds the swagger routes.
// Trying to add the Swagger routes more than once will prevent the application from starting
GlobalConfiguration.Configuration.Routes.Clear();

    然后,应用程序将能够启动,但您将看到两个项目中的操作/功能。从被引用的项目中删除操作...

      创建以下类

      using Swashbuckle.Swagger;
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Web;
      using System.Web.Http.Description;
      
      namespace yournamespace.Models
      
          /// <summary>
          /// This class allows to manage the Swagger document filters.
          /// </summary>
          public class SwaggerCustomOperationsFilter : IDocumentFilter
          
              /// <summary>
              /// Applies the Swagger operation filter to exclude the Swagger operations/functions 
              /// that are inherited by the other Swagger projects referenced.
              /// </summary>
              /// 
              /// <param name="p_swaggerDoc">Swagger document</param>
              /// <param name="p_schemaRegistry">Swagger schema registry</param>
              /// <param name="p_apiExplorer">Api description collection</param>
              public void Apply(SwaggerDocument p_swaggerDoc, SchemaRegistry p_schemaRegistry, IApiExplorer p_apiExplorer)
              
                  IEnumerable<ApiDescription> externalApiDescriptions = p_apiExplorer.ApiDescriptions
                      .Where(d => d.ActionDescriptor.ControllerDescriptor.ControllerType.Module.Name != GetType().Module.Name);
      
                  IEnumerable<int> externalApiDescriptionIndexes = externalApiDescriptions
                      .Select(d => p_apiExplorer.ApiDescriptions.IndexOf(d))
                      .OrderByDescending(i => i);
      
                  IEnumerable<string> externalPaths = externalApiDescriptions.Select(d => $"/d.RelativePathSansQueryString()");
      
                  foreach (string path in externalPaths)
                  
                      p_swaggerDoc.paths.Remove(path);
                  
      
                  foreach (int apiDescriptionIndex in externalApiDescriptionIndexes)
                  
                      p_apiExplorer.ApiDescriptions.RemoveAt(apiDescriptionIndex);
                  
              
          
      
      
      并在SwaggerConfig.cs > Register > GlobalConfiguration.Configuration.EnableSwagger(...) 中添加以下内容
      c.DocumentFilter<SwaggerCustomOperationsFilter>();
      

【讨论】:

【参考方案6】:

此问题的其他原因:

似乎很多人通过删除他们的“bin”和“obj”文件夹来解决这个问题。

但是,问题的原因可能是您在引用的项目中配置 Swagger Config,根据此评论:https://github.com/domaindrivendev/Swashbuckle/issues/364#issuecomment-226013593

当使用 Swagger 的一个项目引用另一个项目时,我收到此错误 与 Swagger 合作的项目。删除引用解决了问题。

这导致我将一些核心功能拆分为我的两个 API 都可以引用的第三个项目,而不是它们相互引用。

【讨论】:

以上是关于为啥我在发布 API 应用程序后收到“名为‘swagger_docs’的路由已在路由集合中”?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我在使用 Google Clas-s-room API 时会收到 404 错误?

为啥我在尝试使用 fetch 连接 Api 时收到“错误请求”错误 400?

为啥我在使用 Google Maps API 时没有收到“同源政策”警告?

为啥我在 AWS API 上收到“无权执行:ecs:ListTasks on resource:*”异常

为啥我在上网几个小时后收到 503 错误?节点/快递

为啥我在运行后在 Flutter 上收到“无法执行 aapt”错误?