Swashbuckle 5找不到我的ApiControllers

我真的需要我的WebAPI 2项目的API文档,我使用了Swashbuckle 5 NuGet包。 开箱即用,我可以点击{myrooturl} / swagger并弹出一个UI,但那里没有控制器,方法或任何东西。 只是我的标题:[base url:/EM.Services,api version: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-50

我还设置了项目的构建以生成XML文档,并将我的SwaggerConfig指向它:

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

我不确定XML文档的工作/不工作是否与它有关,因为我在swagger-ui页面上完全没有控制器。

值得一提的是,我的所有控制器都inheritance自BaseController,而BaseController又inheritance自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().First(); jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); jsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html")); } 

我的具体控制器都看起来像这样(我已经尝试为ApiController调试BaseController并且没有变化):

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

并且我的Base控制器没有做太多(还),只有一个属性:

 [BuildClaims] public abstract class BaseController : ApiController 

空页面持续使用IIS Express或完整的IIS。

更新:我做的一个人为的控制器的例子,这是非常基本的。 它也没有出现,因为我仍然有锅炉板招摇ui没有任何东西。

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

我发现了问题。 在创建一个空的测试项目之后,我注意到WebApiConfiguration是从global.asax app start注册的,而不是OWIN启动类(就像我做的那样)。

由于Swagger / Swashbuckle挂钩到GlobalConfiguration并且还认为OWIN启动和Global.asax存在于不同的上下文中(我认为),修复是将WebAPI内容连接起来从Global.asax注册并使用OWIN的app对象的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中看到控制器和操作。

我被卡住了……这些答案并没有完全帮助我……虽然他们把我带到了那里。 只是为了节省其他人一些时间:

您必须从OWIN传递http配置,然后在其上注册而不是使用GlobalConfiguration类,如下所示:

 //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配置文件中,将register方法更改为:

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

希望这可以帮助。

我发现我遇到了同样的问题。 我创建了一个扩展方法来帮助

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

所有这些解决方案对我来说都很有用,但是对于我的问题,所有这些解决方案都是讨厌的。 经过几个小时的调查后我发现,问题是我还使用Glimpse (或其他改变路由表的包)。

这是一个很好的总结: https : //github.com/domaindrivendev/Swashbuckle/issues/468#issuecomment-139246748

  1. Glimpse在HttpWebRoute之上添加了城堡代理。 所以HostedHttpRouteCollection是RouteProxy的集合而不是HttpWebRoute
  2. APIExplorer类具有FlattenRoutes方法,该方法在HostedHttpRouteCollection上执行foreach循环。
  3. GetEnumerator实现了HostedHttpRouteCollection,专门查找HttpWebRoute。 请参阅下面的代码。 由于glimpse添加了代理,枚举器总是返回0路由!!

      public override IEnumerator GetEnumerator()
     {
          //这里我们只关心Web API路由。
          return _routeCollection
              .OfType()
              .Select(httpWebRoute => httpWebRoute.HttpRoute)
              .GetEnumerator();
     } 

我担心没有解决方案,你可以选择你想要使用的东西: SwashbuckleGlimpse ,但不能同时使用

当然,您可以尝试运行其中一种解决方法,但存在意外行为和棘手错误的风险。

我自己也有同样的问题,这些都没有帮助我。

在一些乱七八糟的事情后,我发现我标记为[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() { 

我不是百分百肯定,但如果重要的话,我也会改变

  public class MyAPIController : Controller 

至:

  public class MyAPIController : System.Web.Http.ApiController 

更准确地说,我删除了System.Web.Mvc的“using”语句,但列出的代码仅用于说明目的。

希望这对未来的其他人有所帮助:)祝你好运!

Swashbuckle位于WebApi的元数据层ApiExplorer 。 它从ApiExplorer获取操作描述,然后将它们映射到Swagger描述。

由于您的控制器inheritance自BASECONTROLLER而不是APICONTROLLER,因此无法使用

根据JimWolleys的评论

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

这是为Swashbuckle提供所有api调用的方法。 它需要一个IApiExplorer。 如果它没有被修改为采取不同的东西,它需要提供默认的ApiExplorer。 其中只包含有关从ApiControllerinheritance的内容的信息

Swashbuckle git repo。 只需搜索GetApiDescriptionsFor,它将直接指向该方法

我发现这个链接非常有用。 此特定解决方案特定于Microsoft.Azure.Mobile.Server API,但它解决了我的问题。

Azure移动应用服务器和Swagger