web-dev-qa-db-ja.com

Swashbuckle 5でApiControllersが見つかりません

私はWebAPI 2プロジェクトのAPIドキュメントが本当に必要な段階にあり、Swashbuckle 5 NuGetパッケージを使用しました。箱から出して{myrooturl}/swaggerを押すとUIがポップアップしますが、コントローラー、メソッド、その他のものはありません。ちょうど私のタイトル:[ベースURL:/EM.Services、APIバージョン:v1]

Swashbuckleのドキュメントを見て、IISでホストされているOWINを使用しているため、SwaggerConfigを次のように変更しました。

c.RootUrl(req => req.RequestUri.GetLeftPart(UriPartial.Authority) + req.GetRequestContext().VirtualPathRoot.TrimEnd('/'));

このドキュメントに従って: https://github.com/domaindrivendev/Swashbuckle/blob/1326e753ce9b3a823b3c156b0b601134692ffc58/README.md#transitioning-to-swashbuckle-5

また、プロジェクトのビルドをセットアップしてXMLドキュメントを生成し、SwaggerConfigにそれを指定しました。

    private static string GetXmlCommentsPath()
    {
        // tried with an without the \bin
        return String.Format(@"{0}\bin\EM.Services.XML", AppDomain.CurrentDomain.BaseDirectory);
    }

Swagger-uiページにコントローラーがまったく表示されないため、XMLドキュメントが正常に機能するかどうかはわかりません。

価値があるのは、すべてのコントローラーがBaseControllerから継承し、BaseControllerがApiControllerから継承することです。

WebApiConfigに何か厄介なことがありますか?

    public static void Register(HttpConfiguration config)
    {

        config.SuppressDefaultHostAuthentication();
        config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

        config.Filters.Add(new ValidateModelAttribute());

        config.Filters.Add(new BaseAuthenticationAttribute());

        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
        jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
        jsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
    }

私の具体的なコントローラーはすべてこのように見えます(ApiControllerのBaseControllerをサブスクライブしてみましたが、変更はありません)。

[RoutePrefix("api/whatever")]
public class FooController : BaseController

そして、私のベースコントローラーは(まだ)多くのことをせず、ただ属性を持っています:

[BuildClaims]
public abstract class BaseController : ApiController

空のページは、IIS Expressまたは完全なIISを使用している間は持続します。

更新:私が作った不自然なコントローラーの例は本当に基本的です。また、何も入っていないボイラープレートswagger uiがまだあるため、表示されません。

/// <summary>
/// I am a test
/// </summary>
[RoutePrefix("api/dummy")]
public class DummyController : ApiController
{
    [HttpGet]
    [Route("foo")]
    public int Foo()
    {
        return 42;
    }
}
24
Bill Sambrone

問題が見つかりました。空のテストプロジェクトを作成した後、OWINスタートアップクラスではなくglobal.asaxアプリの起動からWebApiConfigurationが登録されていることに気付きました(私はそうしました)。

Swagger/SwashbuckleがGlobalConfigurationにフックし、OWINスタートアップとGlobal.asaxが異なるコンテキストに存在することを考えているため(私は思う)、修正は、WebAPIを接続してGlobal.asaxから登録し、OWINのアプリオブジェクトを使用することですWebAPI。

関連ビット:

   // global asax
    protected void Application_Start(object sender, EventArgs e)
    {
        GlobalConfiguration.Configure(WebApiConfig.Register);
       // ... more stuff
    }

   //startup.cs
   public void Configuration(IAppBuilder app)
    {
        // This must happen FIRST otherwise CORS will not work.
        app.UseCors(CorsOptions.AllowAll);

        HttpConfiguration config = new HttpConfiguration();

        ConfigureAuth(app);

        // webapi is registered in the global.asax
        app.UseWebApi(config);

    }

上記のように再配線した後、Swagger UIでコントローラーとアクションを確認できるようになりました。

21
Bill Sambrone

私は立ち往生しました。そして、これらの答えは私を完全に助けませんでした...彼らは私をそこに導いたが。他の人の時間を少しでも節約するために:

次のように、GlobalConfigurationクラスを使用する代わりに、OWINからhttp configを渡して登録する必要があります。

//starup.cs
public void Configuration(IAppBuilder app)
    {
        Config = new HttpConfiguration();
        WebApiConfig.Register(Config);

        app
            .UseResponseLogging()
            .UseRequestLogging()
            .UseHttpErrors()
            .UseExceptionLogging()
            .UseWebApi(Config);

        HandlerConfig.Register(Config);

        SwaggerConfig.Register(Config);
    }

そして、swagger構成ファイルで、登録方法を次のように変更します。

public static void Register(HttpConfiguration config)
    {
        var thisAssembly = typeof(SwaggerConfig).Assembly;

        config
            .EnableSwagger(c =>
                {...

お役に立てれば。

19
Sumit Maingi

私は同じ問題を抱えていることがわかりました。役立つ拡張メソッドを作成しました

using Swashbuckle.Application;
using System.Web.Http;

public static class SwaggerExtensions
{
    public static HttpConfiguration EnableSwagger(this HttpConfiguration httpConfiguration)
    {
        httpConfiguration
            .EnableSwagger(c => c.SingleApiVersion("v1", "A title for your API"))
            .EnableSwaggerUi();
        return httpConfiguration;
    }
}

その後、私のStartup.csで

public class Startup
{
    public void Configuration(IAppBuilder appBuilder)
    {
        HttpConfiguration httpConfiguration = new HttpConfiguration();

        httpConfiguration
            .EnableSwagger()    // <==== EXTENSION METHOD <==== //
            .MapHttpAttributeRoutes();

        httpConfiguration.Routes.MapHttpRoute(
            "DefaultApi",
            "api/{controller}/{id}",
            new {id = RouteParameter.Optional});

        appBuilder
            .UseWebApi(httpConfiguration);
    }
}
3
chris31389

これらのソリューションはすべて私にとってはうまくいきますが、それらはすべて私の問題に対する厄介なハックです。数時間の調査の後、問題はGlimpse(またはルートテーブルを変更する他のパッケージ)も使用していることがわかりました。

ここに素晴らしい要約があります: https://github.com/domaindrivendev/Swashbuckle/issues/468#issuecomment-139246748

  1. Glimpseは、HttpWebRouteの上に城のプロキシを追加します。したがって、HostedHttpRouteCollectionはRouteProxyのコレクションであり、HttpWebRouteではありません。
  2. APIExplorerクラスには、HostedHttpRouteCollectionでforeachループを実行するFlattenRoutesメソッドがあります。
  3. GetEnumeratorHostedHttpRouteCollectionの実装は、特にHttpWebRouteを探します。以下のコードを参照してください。 glimpseがプロキシを追加したため、列挙子は常に0ルートを返します!!

    public override IEnumerator GetEnumerator()
     {
     //ここでは、Web APIルートのみを考慮します。
     return _routeCollection 
     .OfType()
     Select(httpWebRoute => httpWebRoute.HttpRoute)
     .GetEnumerator(); 
    }

解決策がないので、使用したいものを選択できます:SwashbuckleまたはGlimpse、しかし両方一緒ではない

もちろん、これらの回避策のいずれかで実行を試みることもできますが、予期しない動作や厄介なバグのリスクがあります。

3
Marek Dorda

私は自分で同じ問題を抱えていましたが、これらのどれも私を助けませんでした。

少しいじってから、[System.Web.Mvc.Route("visit")]とラベル付けしたルートがswaggerによって発見されていないことがわかりました。

_    [HttpGet]
    // ROUTE ATTRIBUTE NOT FOUND BY SWAGGER
    [System.Web.Mvc.Route("visit")]
    public string Visit()
    {
_

しかし[System.Web.Http.Route("visit")]

_    [HttpGet]
    // ROUTE ATTRIBUTE *IS* FOUND BY SWAGGER
    [System.Web.Http.Route("visit")]
    public string Visit()
    {
_

100%確信はありませんが、重要な場合は、

_ public class MyAPIController : Controller
_

に:

_ public class MyAPIController : System.Web.Http.ApiController
_

より正確には、System.Web.Mvcの「using」ステートメントを削除しましたが、コードは説明のためにリストされています。

これが将来誰かに役立つことを願っています:)頑張ってください!

2
Alex C

Owin + Swashbuckleの統合には多くの問題がありましたが、これらの答えのどれも私にとってすべてを解決するものではありませんでした。簡単に言えば、私はすべてを解決し、それを必要とするすべての人のテンプレートとして使用されるオープンソースリポジトリを作成しました。

確認してください: ASPSwaggerOwinTemplate

1
Crimson7

SwashbuckleはWebApiのメタデータレイヤーApiExplorerの上にあります。 ApiExplorerから操作の説明を取得し、Swaggerの説明にマップします。

コントローラーはAPICONTROLLERではなくBASECONTROLLERを継承するため、機能しません

JimWolleysのコメントごと

 private IEnumerable<ApiDescription> GetApiDescriptionsFor(string apiVersion)
    {
        return (_options.VersionSupportResolver == null)
            ? _apiExplorer.ApiDescriptions
            : _apiExplorer.ApiDescriptions.Where(apiDesc => _options.VersionSupportResolver(apiDesc, apiVersion));
    }

これは、すべてのAPI呼び出しを取得するためにSwashbuckleを強化するメソッドです。 IApiExplorerが必要です。異なるものを使用するように変更されていない場合、提供されているデフォルトのApiExplorerを使用します。 ApiControllerから継承するものに関する情報のみを保持している

Swashbuckle gitリポジトリ。GetApiDescriptionsForを検索するだけで、メソッドに直接移動します

1
gh9

このリンクは非常に役立つことがわかりました。この特定のソリューションはMicrosoft.Azure.Mobile.Server APIに固有のものですが、私にとっては問題を解決しました。

Azure Mobile AppsサーバーとSwagger

0
Rod Hartzell