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
- Glimpse在HttpWebRoute之上添加了城堡代理。 所以HostedHttpRouteCollection是RouteProxy的集合而不是HttpWebRoute 。
- APIExplorer类具有FlattenRoutes方法,该方法在HostedHttpRouteCollection上执行foreach循环。
GetEnumerator实现了HostedHttpRouteCollection,专门查找HttpWebRoute。 请参阅下面的代码。 由于glimpse添加了代理,枚举器总是返回0路由!!
public override IEnumerator GetEnumerator() { //这里我们只关心Web API路由。 return _routeCollection .OfType() .Select(httpWebRoute => httpWebRoute.HttpRoute) .GetEnumerator(); }
我担心没有解决方案,你可以选择你想要使用的东西: Swashbuckle或Glimpse ,但不能同时使用 。
当然,您可以尝试运行其中一种解决方法,但存在意外行为和棘手错误的风险。
我自己也有同样的问题,这些都没有帮助我。
在一些乱七八糟的事情后,我发现我标记为[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
- 使用ASP.NET Web API,控制器如何返回使用DotNetZip Library压缩的流图像集合?
- ASP.NET Odata Web API的error handling
- ASP.NET中的HostingEnvironment.QueueBackgroundWorkItem()用于小型后台任务
- 当代码的所有部分都不是异步时,异步Web服务有什么好处
- 在WebApi服务中validationAzure移动服务令牌
- MultipartMemoryStreamProvider:filename?
- 如何防止ReadAsStringAsync返回双重转义的字符串?
- Web API读取控制器构造函数中的标头值
- 在包含Controllers和ApiControllers的项目中从ApiController和Action名称获取Url