为什么我在发布 API 应用程序后得到 "A route named 'swagger_docs' is already in the route collection"?

Why am I getting "A route named 'swagger_docs' is already in the route collection" after I publish my API App?

发布我的 API 应用程序后,出现 ASP.NET 的黄色错误屏幕。错误消息显示 "A route named 'swagger_docs' is already in the route collection"。

我该如何解决这个问题?

这与 API 应用程序本身无关,但与 Web API 有关。触发错误的原因非常简单:

  1. 您发布了基于 Web API 的 API 应用程序 API。
  2. 您放弃了您的项目并开始开发基于 Web API
  3. 的新 API 应用程序
  4. 您想发布新的 API 应用程序,而不是您在第 1 步创建的旧 API 应用程序。
  5. 您在 "Publish.." 期间 select API 应用程序,您将获得我们在第 1 步部署的现有 API 应用程序的发布配置文件。
  6. 您使用 Web 部署和发布配置文件进行部署,新 API 应用程序位于旧应用程序之上。

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

要解决此问题,请在 Web 部署期间单击“设置”选项卡,然后展开 "File Publish Options"。那里有一个复选框,名为 "Remove additional files from destination"。这将解决问题,因为它只会将您部署的文件留在目的地,而不是旧文件。

希望对您有所帮助。

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

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

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 文件的汇编调用。

应该可以。

此问题的其他原因:

似乎很多人通过根据其他答案删除他们的 "bin" 和 "obj" 文件夹来解决这个问题。

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

I received this error when one project with Swagger referenced another project with Swagger. Removing the reference fixed the problem.

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

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

  1. 删除 SwaggerConfig.cs > RegisterGlobalConfiguration.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();
  1. 然后,应用程序就可以启动了,但是你会看到两个项目中都有的operations/functions。要从被引用的项目中删除操作...

    1. 创建以下class

      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);
                  }
              }
          }
      }
      
    2. 并在 SwaggerConfig.cs > Register > GlobalConfiguration.Configuration.EnableSwagger(...) 中添加以下内容
      c.DocumentFilter<SwaggerCustomOperationsFilter>();
      

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

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