wake-up-neo.net

Swashbuckle 5 kann meine ApiControllers nicht finden

Ich bin an einem Punkt, an dem ich wirklich eine API-Dokumentation für mein WebAPI 2-Projekt benötige, und ich habe das Swashbuckle 5 NuGet-Paket verwendet. Nach dem Auspacken kann ich {myrooturl}/swagger treffen und eine Benutzeroberfläche erscheint, aber es gibt keine Controller, Methoden oder irgendetwas. Nur mein Titel: [Basis-URL: /EM.Services, API-Version: v1]

Ich habe mir die Swashbuckle-Dokumente angesehen und da ich OWIN verwende, das von IIS gehostet wird, habe ich die SwaggerConfig mit folgendem geändert:

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

gemäß diesem Dokument: https://github.com/domaindrivendev/Swashbuckle/blob/1326e753ce9b3a823b3c156b0b601134692ffc58/README.md#transitioning-to-swashbuckle-50

Ich habe den Build des Projekts auch so eingerichtet, dass er die XML-Dokumente generiert, und mein SwaggerConfig darauf verwiesen:

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

Ich bin mir nicht sicher, ob die funktionierenden/nicht funktionierenden XML-Dokumente etwas damit zu tun haben, da ich absolut keine Controller auf der swagger-ui-Seite bekomme.

Für alles, was es wert ist, erben alle meine Controller von einem BaseController, der wiederum von ApiController erbt.

Ist mit meiner WebApiConfig etwas schief gelaufen?

    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"));
    }

Meine konkreten Controller sehen alle so aus (ich habe versucht, BaseController für ApiController auszuspielen und es gibt keine Änderung):

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

und mein Basiscontroller macht (noch) nicht viel, hat nur ein Attribut:

[BuildClaims]
public abstract class BaseController : ApiController

Die leere Seite bleibt bei Verwendung von IIS Express oder IIS vollständig erhalten.

Update: Beispiel eines von mir entwickelten Controller, der wirklich grundlegend ist. Es erscheint auch nicht, da ich immer noch die Boilerplatte mit nichts dran habe.

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

Ich habe das Problem gefunden. Nachdem ich ein leeres Testprojekt erstellt hatte, bemerkte ich, dass die WebApiConfiguration vom Start der global.asax-App und nicht von der OWIN-Startklasse (wie ich) registriert wurde.

Da sich Swagger/Swashbuckle in die GlobalConfiguration einhakt und auch, dass OWIN-Startup und Global.asax in verschiedenen Kontexten (ich denke) leben, besteht die Lösung darin, Ihre WebAPI-Daten zu verbinden, um sich bei Global.asax zu registrieren und um das App-Objekt von OWIN zu verwenden WebAPI.

Relevante Bits:

   // 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);

    }

Nach der Neuverkabelung wie oben, kann ich jetzt Controller und Aktionen in der Swagger-Benutzeroberfläche sehen.

21
Bill Sambrone

Ich blieb hängen ... und diese Antworten haben mir nicht voll geholfen ... obwohl sie mich dorthin geführt haben. Nur um anderen Menschen etwas Zeit zu sparen:

Sie müssen die http-Konfiguration von OWIN übergeben und sich dann registrieren, anstatt die GlobalConfiguration-Klasse wie folgt zu verwenden:

//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);
    }

Ändern Sie in der Swagger-Konfigurationsdatei die Registermethode in:

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

        config
            .EnableSwagger(c =>
                {...

Hoffe das hilft.

17
Sumit Maingi

Ich stellte fest, dass ich das gleiche Problem hatte. Ich habe eine Erweiterungsmethode erstellt, um zu helfen

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;
    }
}

Dann in meiner 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

Alle diese Lösungen funktionieren für mich, aber alle sind nur böse Hacks für mein Problem. Nach einigen Stunden der Untersuchung habe ich herausgefunden, dass das Problem darin liegt, dass ich auch Glimpse (oder andere Pakete, die die Routentabelle ändern) verwende.

Hier ist eine großartige Zusammenfassung: https://github.com/domaindrivendev/Swashbuckle/issues/468#issuecomment-139246748

  1. Glimpse fügt Schlossproxys auf HttpWebRoute hinzu. HostedHttpRouteCollection ist also eine Auflistung von RouteProxy und nicht HttpWebRoute.
  2. Die APIExplorer-Klasse verfügt über die Methode FlattenRoutes, die eine Foreach-Schleife über HostedHttpRouteCollection durchführt.
  3. GetEnumerator Die Implementierung von HostedHttpRouteCollection sucht speziell nach HttpWebRoute. Siehe den Code unten. Seit dem blick hat Proxys hinzugefügt, Enumerator gibt immer 0 Routen zurück !!

    public überschreibt IEnumerator GetEnumerator () 
     {
     // Hier kümmern wir uns nur um Web-API-Routen .
     return _routeCollection 
     .OfType () 
     .Wählen Sie (httpWebRoute => httpWebRoute.HttpRoute) 
     .GetEnumerator (); 
    }

Ich fürchte, es gibt keine Lösung, Sie können wählen, was Sie verwenden möchten: Swashbuckle oder Glimpse, aber nicht beides zusammen.

Natürlich können Sie versuchen, eine dieser Problemumgehungen auszuführen, aber es besteht die Gefahr unerwarteten Verhaltens und kniffliger Fehler.

3
Marek Dorda

Ich hatte viele Probleme mit der Integration von Owin + Swashbuckle und keine dieser Antworten hat alles für mich behoben. Kurz gesagt, ich habe alles gelöst und ein Open-Source-Repo erstellt, das als Vorlage für alle verwendet werden kann, die es benötigen.

Bitte überprüfen Sie: ASPSwaggerOwinTemplate

1
Crimson7

Ich hatte gerade das gleiche Problem und nichts davon hat mir geholfen.

Nach einigem Durcheinander fand ich heraus, dass die Routen, die ich als [System.Web.Mvc.Route("visit")] bezeichnet hatte, nicht von Swagger entdeckt wurden.

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

aber [System.Web.Http.Route("visit")] ist

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

Ich bin nicht 100% sicher, aber wenn es darauf ankommt, habe ich auch gewechselt

 public class MyAPIController : Controller

zu:

 public class MyAPIController : System.Web.Http.ApiController

Genauer gesagt, ich habe die "using" -Anweisung für System.Web.Mvc entfernt, der Code ist jedoch zu Illustrationszwecken aufgeführt.

Hoffe das hilft in Zukunft jemand anderem :) Viel Glück!

1
Alex C

Ich fand diesen Link sehr hilfreich. Diese spezielle Lösung ist spezifisch für eine Microsoft.Azure.Mobile.Server-API, hat aber das Problem für mich gelöst.

Azure Mobile Apps Server und Swagger

0
Rod Hartzell

Swashbuckle befindet sich auf dem Metadaten-Layer ApiExplorer von WebApi. Die Operationsbeschreibungen werden vom ApiExplorer übernommen und dann den Swagger-Beschreibungen zugeordnet.

Da Ihr Controller von BASECONTROLLER und nicht von APICONTROLLER erbt, funktioniert er nicht

Per JimWolleys Kommentar

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

dies ist die Methode, mit der Swashbuckle alle Aufrufe der APIs erhält. Es braucht einen IApiExplorer. Wenn es nicht geändert wurde, um etwas anderes zu akzeptieren, ist der standardmäßige ApiExplorer erforderlich. Welches nur Informationen über Dinge enthält, die von ApiController erben

Swashbuckle Git Repo. Suchen Sie einfach nach GetApiDescriptionsFor und Sie gelangen direkt zur Methode

0
gh9