web-dev-qa-db-ja.com

APIアプリを公開した後、「「swagger_docs」という名前のルートがすでにルートコレクションにあります」というメッセージが表示されるのはなぜですか?

APIアプリを公開した後、ASP.NETの黄色のエラー画面が表示されます。エラーメッセージには、「「swagger_docs」という名前のルートがすでにルートコレクションにあります」と表示されます。

どうすればこれを修正できますか?

16
Panos

これは、APIアプリ自体とは関係ありませんが、WebAPIに関するものです。エラーのトリガーは非常に簡単です。

  1. WebAPIに基づくAPIアプリを公開します。
  2. プロジェクトを破棄し、WebAPIに基づく新しいAPIアプリの作業を開始します
  3. 手順1で作成した古いAPIアプリではなく、新しいAPIアプリを公開する必要があります。
  4. 「公開..」でAPIアプリを選択すると、手順1でデプロイした既存のAPIアプリの公開プロファイルが取得されます。
  5. Web配置と公開プロファイル、古いAPIアプリの上に新しいAPIアプリを使用してデプロイします。

それは私が前に説明した問題を引き起こします。これは、アプリを起動しようとしたときにSwashbuckleによって登録されているルートが2つあるために発生します。古いものと新しいものの1つ。これは、古いファイルが宛先にまだ存在しているためです。

これを解決するには、Web展開中に、[設定]タブをクリックし、[ファイルの公開オプション]を展開します。 「宛先から追加のファイルを削除する」というチェックボックスがあります。これにより、デプロイしたファイルのみが残り、古いファイルは残らないため、問題が修正されます。

Settings -> File Publish Options

それが役に立てば幸い。

38
Panos

アプリをローカルでデバッグしようとしたときに発生した場合はどうなりますか?これは私のために起こりました、そしてその理由は、私が私のアセンブリ名を改名したからです。そのため、binフォルダーには、同じプロジェクトに対して異なる名前の2つのdllがあり、このエラーが発生していました。古い名前のdllを削除すると、すべて問題ありません。お役に立てれば。

10
Venu

これは、以下で説明するように、おそらく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ファイルのAssembly呼び出しを削除する必要があります。

動作するはずです。

6
Sales Lopes

私の解決策と原因:
NamesSpaces、Refactoredなどの名前を変更したときに同じ問題が発生しました。
他のみんながやったことを読んだ後、私が試したことは次のとおりです。

  • VisualStudioでソリューションをクリーンアップしました
  • ビンフォルダを手動でクリーンアップしました
  • プロジェクトプロパティの名前空間を確認しました(念のためコピーしました)>>Buildタブ>>Outputまでスクロールダウンし、XMLドキュメントファイルを確認します) 正しい。この名前は後で必要になります。
  • 開いた:SwaggerConfig.cs >>ここの名前空間を修正(コピー、貼り付け)c.SingleApiVersion( "vX"、 "NameSpace")
  • 見つかるまで下にスクロールしました:GetXmlCommentsPath()は、.xmlファイルパスに正しい名前空間をコピーして貼り付けました。
  • ラン、スモークテスト、この投稿を終了しました。
1
Manuel Plaza

私の問題は、Swashbuckle拡張機能を持つ別のプロジェクトを参照していたことでした。参照されたプロジェクトの内容を変更せずに、両方のプロジェクトを保持する方法は次のとおりです。

  1. GlobalConfiguration.Configuration.EnableSwagger(...).EnableSwaggerUi(...);の直前に_SwaggerConfig.cs_> Registerで参照されているプロジェクトによって作成されたルートを削除します。
_// 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. その後、アプリケーションを起動できるようになりますが、両方のプロジェクトにある操作/機能が表示されます。参照されているプロジェクトから操作を削除するには...

    1. 次のクラスを作成します

      _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>();
      _

この問題の別の原因:

多くの人が、他の回答に従って「bin」フォルダと「obj」フォルダを削除することでこの問題を解決しているようです。

ただし、このコメントのように、参照されているプロジェクトでSwagger Configを構成していることが問題の原因である可能性があります: https://github.com/domaindrivendev/Swashbuckle/issues/364#issuecomment-22601359 ==

Swaggerを使用する1つのプロジェクトが、Swaggerを使用する別のプロジェクトを参照したときにこのエラーが発生しました。参照を削除すると、問題が修正されました。

これにより、いくつかのコア機能を、相互に参照するのではなく、両方のAPIが参照できる3番目のプロジェクトに分割しました。

0
Morvael