我真的需要我的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('/'));
我还设置了项目的构建以生成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页面上完全没有控制器。
值得一提的是,我的所有控制器都继承自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
并且我的Base控制器没有做太多(还),只有一个属性:
[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;
}
}
我发现了这个问题。在创建一个空的测试项目之后,我注意到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")]
的路线并没有被昂首阔步发现。
[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描述。
由于您的控制器继承自BASECONTROLLER而不是APICONTROLLER,因此无法使用
根据JimWolleys的评论
private IEnumerable<ApiDescription> GetApiDescriptionsFor(string apiVersion)
{
return (_options.VersionSupportResolver == null)
? _apiExplorer.ApiDescriptions
: _apiExplorer.ApiDescriptions.Where(apiDesc => _options.VersionSupportResolver(apiDesc, apiVersion));
}
这是为Swashbuckle提供所有api调用的方法。它需要一个IApiExplorer。如果它没有被修改为采取不同的东西,它需要提供默认的ApiExplorer。其中只包含有关从ApiController继承的内容的信息
我发现这个链接非常有用。此特定解决方案特定于Microsoft.Azure.Mobile.Server API,但它解决了我的问题。
我在Owin + Swashbuckle集成方面遇到了很多问题,这些答案都没有为我解决所有问题。简而言之,我设法解决了所有问题并创建了一个开源代码库,用作任何需要它的人的模板。