33

我现在确实需要我的 WebAPI 2 项目的 API 文档,并且我使用了 Swashbuckle 5 NuGet 包。开箱即用,我可以点击 {myrooturl}/swagger 并弹出一个 UI,但其中没有控制器、方法或任何东西。只是我的标题:[基本网址:/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-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 页面上绝对没有控制器。

值得一提的是,我的所有控制器都继承自 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"));
    }

我的具体控制器看起来都是这样的(我尝试将 BaseController 替换为 ApiController 并且没有任何变化):

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

而我的 Base 控制器(还)做的不多,只是有一个属性:

[BuildClaims]
public abstract class BaseController : ApiController

使用 IIS Express 或完整的 IIS 时,空白页面仍然存在。

更新:我制作的一个非常基本的人为控制器的示例。它也没有出现,因为我仍然有样板招摇 ui,里面什么都没有。

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

11 回答 11

29

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

您必须从 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 配置文件中,将注册方法更改为:

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

        config
            .EnableSwagger(c =>
                {...

希望这可以帮助。

于 2016-09-08T11:54:42.797 回答
23

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

由于 Swagger/Swashbuckle 与 GlobalConfiguration 挂钩,并且还考虑到 OWIN 启动和 Global.asax 存在于不同的上下文中(我认为),因此解决方法是将您的 WebAPI 内容连接到从 Global.asax 注册并使用 OWIN 的应用程序对象网络API。

相关位:

   // 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 中看到控制器和操作。

于 2015-08-07T20:26:14.447 回答
5

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

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);
    }
}
于 2017-07-25T08:24:22.543 回答
4

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

经过一番折腾后,我发现我标记为的路线[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()
    {

我不是 100% 确定,但如果重要的话,我也从

 public class MyAPIController : Controller

至:

 public class MyAPIController : System.Web.Http.ApiController

更准确地说,我删除了 System.Web.Mvc 的“使用”语句,但列出代码是为了说明。

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

于 2017-11-15T14:41:24.743 回答
3

所有这些解决方案都对我有用,但它们都只是我的问题的讨厌的黑客。经过几个小时的调查,我发现问题在于我还使用了Glimpse(或其他更改路由表的软件包)。

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

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

    公共覆盖 IEnumerator GetEnumerator()
    {
         // 这里我们只关心 Web API 路由。
         返回 _routeCollection
             .OfType()
             .Select(httpWebRoute => httpWebRoute.HttpRoute)
             .GetEnumerator();
    }

我害怕没有解决方案,你可以选择你想使用的:SwashbuckleGlimpse,但不能同时使用

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

于 2017-08-29T05:59:35.370 回答
1

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 继承的事物的信息

Swashbuckle git 存储库。只需搜索 GetApiDescriptionsFor,它会直接带您进入该方法

于 2015-08-05T18:58:30.817 回答
1

我在 Owin + Swashbuckle 集成方面遇到了很多问题,这些答案都没有为我解决所有问题。长话短说,我设法解决了所有问题,并创建了一个开源存储库,用作任何需要它的人的模板。

请检查:ASPSwaggerOwinTemplate

于 2019-04-25T05:26:53.327 回答
0

就我而言,我遇到了与 Alex C 类似的问题。我必须做两件事来解决它:

第一件事是我有一个关于使用 MVC 的导入声明,如下所示:

using System.Web.Mvc;

我删除了那个导入语句,解决了一半的问题。我注意到的另一件事是,在 Swashbucke 中出现的一个控制器有一个这样的注释

[RoutePrefix("v1/Awesome")]

Awesome控制器 AwesomeController 的名称在哪里。所以我把那个路由前缀注释放在我的类声明之前,现在它显示在 Swagger 界面中

[RoutePrefix("v1/Amazing")]
public class AmazingController : ApiController

因此,如果其他人遇到此问题,您可以检查是否需要像我一样添加路由前缀。

于 2021-02-09T23:48:34.570 回答
0

我在使用 OWIN 时也遇到了这个问题。通过按照此处的建议仅安装 Swashbuckler Core并通过如下编辑 Startup.cs 解决了该问题:

// Startup.cs
            // ...
            HttpConfiguration config = new HttpConfiguration();
            // ...
            config
                .EnableSwagger(c =>
                {
                    ////add if there's custom root path
                    //c.RootUrl(req =>
                    //    req.RequestUri.GetLeftPart(UriPartial.Authority) +
                    //    req.GetRequestContext().VirtualPathRoot.TrimEnd('/'));

                    c.SingleApiVersion("v1", "A title for your API");
                })
                .EnableSwaggerUi();
            // ...
            appBuilder.UseWebApi(config);
于 2020-04-03T16:44:16.583 回答
0

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

Azure 移动应用服务器和 Swagger

于 2017-03-28T11:57:28.740 回答
0

我熟悉自动扩展控制器的 .NET 核心版本的 Swashbuckle。当我在开发一个框架(非核心)API 时,当我终于设法让一些东西显示出来时,我很困惑,因为我不知道点击显示/隐藏并且仍然认为它不起作用。

在此处输入图像描述

默认情况下,您可以使用以下内容扩展它:

.EnableSwaggerUi(c => {
    c.DocExpansion(DocExpansion.List);
});
于 2021-01-04T23:38:39.340 回答