ASP.NET Core - Swashbuckle未创建swagger.json文件

114

我无法让 Swashbuckle.AspNetCore (1.0.0) 包生成任何输出。我阅读到 swagger.json 文件应该写入 '~/swagger/docs/v1'。但是,我没有得到任何输出。

我从一个全新的 ASP.NET Core API 项目开始。我应该提到这是 ASP.NET Core 2。API 可以正常工作,并且我能够从 values 控制器检索值。

我的启动类配置与此文章中描述的完全相同 (Swashbuckle.AspNetCore on GitHub)。

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();

        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
        });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();

            // Enable middleware to serve generated Swagger as a JSON endpoint.
            app.UseSwagger();
            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "MyAPI V1");
            });
        }
        else
        {
            app.UseExceptionHandler();
        }

        app.UseStatusCodePages();
        app.UseMvc();

        //throw new Exception();
    }
}

您可以查看 NuGet 引用...

enter image description here

再次强调,这是所有默认模板,但我包含了 ValuesController 作为参考...

[Route("api/[controller]")]
public class ValuesController : Controller
{
    // GET api/values
    [HttpGet]
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }

    // GET api/values/5
    [HttpGet("{id}")]
    public string Get(int id)
    {
        return "value";
    }

    // POST api/values
    [HttpPost]
    public void Post([FromBody]string value)
    {
    }

    // PUT api/values/5
    [HttpPut("{id}")]
    public void Put(int id, [FromBody]string value)
    {
    }

    // DELETE api/values/5
    [HttpDelete("{id}")]
    public void Delete(int id)
    {
    }
}

1
检查在Visual Studio中的输出 - hosam hemaily
并不总是显而易见的,但当你发布时,请确保它在“开发”环境中发布,除非你真的想要在发布或生产环境中使用 Swagger。 - RetroCoder
有没有人对 AKS 有解决方案? - John Nyingi
https://dev59.com/OVIG5IYBdhLWcg3w42Bn - KushalSeth
39个回答

85

我曾经也遇到了同样的问题,请检查http://localhost:XXXX/swagger/v1/swagger.json。如果出现任何错误,请修复它们。

举个例子,我在基本控制器类中有一个模棱两可的路由,然后我收到了这个错误:"Ambiguous HTTP method for action. Actions require an explicit HttpMethod binding for Swagger 2.0." 如果你使用基础控制器,请确保你的公共方法使用HttpGet/HttpPost/HttpPut/HttpDelete 或 Route属性以避免产生模糊的路由。

同时,我还定义了HttpGet("route")和Route("route")属性在同一个方法中,这也是导致Swagger出错的最后一个问题。


4
哦,太感谢了,你的第一个段落帮了我大忙!我意识到 swagger.json 文件不在的原因是由于 API 控制器中存在错误,这些错误阻止了 swagger 生成 json 文件。一旦我解决了所有错误,swagger UI 就重新出现了!查看指向 swagger.json 的URL时,它会抛出错误,这真的对解决问题很有帮助!!! - Franva
2
我曾经遇到过同样的问题,我的一个删除端点没有完全实现并使用了Route属性。一旦我将该端点的Route属性更改为HttpDelete,错误就消失了。谢谢@Marisol。 - Hari Krishna Gaddipati
1
此外,错误可能实际上并没有在您的浏览器中显示出来。以调试模式运行您的应用程序,并打开所有CLR异常的中断。当您加载swagger.json的URL时,该异常将被抛出并显示给您。这应该包含为什么swagger.json文件未被生成的详细信息。 - Robert P

71

我相信您在配置中错过了这两行:

if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();

    // Enable middleware to serve generated Swagger as a JSON endpoint.
    app.UseSwagger();
    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint("v1/swagger.json", "MyAPI V1");
    });
}

要访问Swagger UI,URL应该是:http://localhost:XXXX/swagger/

JSON可以在Swagger UI的顶部找到:

enter image description here


3
实际上,在"env.IsDevelopment"这行代码之前,我已经加入了"app.UseSwagger",但是我把它移到了那段代码里面,并添加了"app.UseSwaggerUI",但问题依旧存在。我更新了我的问题以反映新的代码。 - John Livermore
7
现在我也感到困扰。我不知道它是否真的创建了一个文件,还是仅仅动态生成JSON并未保存它。 - Tiago B
27
为了避免 IIS 路径别名问题,请从 URL 路径中删除“/swagger/”。它应该如下所示:app.UseSwaggerUI(c => { c.SwaggerEndpoint("v1/swagger.json", "API 名称"); }); - 2b77bee6-5445-4c77-b1eb-4df3e5
3
谢谢 @2b77bee6-5445-4c77-b1eb-4df3e5,这对我非常有效。 - Appulus
1
@Eru 很高兴能帮到你,我刚把它添加为答案。 - 2b77bee6-5445-4c77-b1eb-4df3e5
显示剩余9条评论

52

如果您的应用程序托管于IIS/IIS Express,请尝试以下方法:

c.SwaggerEndpoint("../swagger/v1/swagger.json", "MyAPI V1");

1
只有这个答案有效。非常感谢。您能否详细说明原因? - Saurabh
1
这也是我解决问题的方法。不过我不确定为什么。 - mariocatch
一样,这正是我需要的IIS托管。我猜 "../" 允许相对URL托管。非常感谢! - Brian

36

我遇到了与Swagger类似但不完全相同的问题。希望这能帮助其他人。

我正在使用自定义文档标题,并且没有更改SwaggerEndPoint中的文件夹路径以匹配文档标题。如果你将终点指向swagger/v1/swagger.json,那么在Swagger UI中就找不到JSON文件。

示例:

services.AddSwaggerGen(swagger =>
{
    swagger.SwaggerDoc("AppAdministration", new Info { Title = "App Administration API", Version = "v1.0" });
            
});


app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("/swagger/AppAdministration/swagger.json", "App Administration");
});

哇,这似乎很随机。(在我的情况下它起作用了,谢谢。) - Nikola Novak

31
#if DEBUG
   // For Debug in Kestrel
   c.SwaggerEndpoint("/swagger/v1/swagger.json", "Web API V1");
#else
   // To deploy on IIS
   c.SwaggerEndpoint("/webapi/swagger/v1/swagger.json", "Web API V1");
#endif

在部署到IIS的WebAPI中,应用程序别名是基本URL。您需要确保所有IIS部署的应用程序别名(基本URL)相同,因为Swagger会在“/swagger/v1/swagger.json”位置查找swagger.json,但不会添加应用程序别名(基本URL),这就是它无法工作的原因。

例如:

localhost/swagger/v1/swagger.json - 找不到swagger.json


最好使用 SwaggerUIOptions.RoutePrefix 来定义 webapi 前缀(使用配置中的值),而不是硬编码。 - oleksa

28

您必须遵守两个规则:

  1. 使用明确的 Http 动词修饰所有操作,如[HttpGet("xxx")][HttpPost("xxx")]等,而不是使用[Route("xxx")]
  2. 在控制器中的公共方法上使用[NonAction] 属性。

请注意,http://localhost:XXXX/swagger/页面请求http://localhost:XXXX/swagger/v1/swagger.json文件,但如果您不遵守以上规则,则会从 Swagger 中发生异常。


1
对我来说,只需要添加[NonAction][Route("xxx")]即可。 - Oleg Sh
我正在使用.NET 5控制器,并针对IActionFilter实现了OnActionExecuting()/OnActionExecuted()。在这些方法上添加[NonAction]属性对我很有帮助。 - Jason Snelders
1
@MohammadBarbast 仅为澄清起见,我在第二个项目符号中使用了 [NonAction] 而不是 [NoAction],因为 .NET 5 中不存在 [NoAction] 属性(不确定您是否有打字错误或它曾经存在于以前的 Core 版本中并已更改)。 - Jason Snelders

17

在查看了答案并检查了建议后,我最终不知道出了什么问题。

我真的尝试了所有方法。因此,如果你遇到同样的情况,请理解问题可能是其他东西引起的,与swagger完全无关。

在我的情况下,是一个 OData 异常。

以下是步骤:

1) 访问 localhost:xxxx/swagger
2) 打开开发人员工具
3) 单击控制台中显示的错误,您将看到导致问题的内部异常。


1
同样的问题,开发者工具显示路径指向本地主机根目录,而不是默认站点下的特定应用程序。 - Peter PitLock
在查看了网页控制台之后,我发现文档创建失败是因为我有两个不同的入口模型名称相同。感谢你指出正确的方向,伙计。 - Ramiro G.M.

16

因为我的评论似乎有帮助,所以我将其转移到答案部分。


为避免与IIS别名产生问题,请从URL路径中删除/swagger/。它应该像这样:

app.UseSwaggerUI(c => { c.SwaggerEndpoint("v1/swagger.json", "API name"); });

10

我不确定这对某个人是否有用,但在我的情况下,问题在于名称的大小写不同。

服务配置中的V1 - V 大写字母
设置中的v1 - v 小写字母

我所做的唯一事情就是使用相同的大小写,然后它就起作用了。

带有大写V版本名称


面对同样的问题,我发现在声明SwaggerDoc和SwaggerEndpoint配置时使用了不匹配的版本。当我修正了版本后,一切都开始正常工作了。 - Zhuravlev A.
谢谢您。这实际上是最好的答案。SwaggerDoc(name)必须与SwaggerDoc(OpenApi -> Version)SwaggerEndpoint(url)的值相同。因此,SwaggerUI将路由到正确的swagger文件。 - Triet Nguyen

8

如果您在控制器中映射到唯一的URL时遇到任何问题,将会出现此错误。

查找问题原因的最佳方法是从项目中排除所有控制器。然后尝试启用一个控制器或者控制器中的一个或多个方法,以逐个查找有问题的控制器/控制器方法(S)。 或者你可以变得聪明点,使用二分搜索逻辑来禁用和启用多个控制器/方法来查找有问题的控制器/方法。

其中一些原因包括:

  1. 在控制器中具有公共方法但没有HTTP方法属性

  2. 具有多个具有相同HTTP属性的方法,如果您没有使用“[action]”基于映射,则可能会映射到同一个API调用

  3. 如果您正在使用版本控制,请确保在所有控制器版本中都有该方法(即使使用了继承,也要从基类中使用)


我有两个HTTPGET,它们的签名不同,但是一旦我删除了我的新的那一个,我的错误就消失了。 - Zoey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接