【问题标题】:ASP.NET Core - Swashbuckle not creating swagger.json fileASP.NET Core - Swashbuckle 不创建 swagger.json 文件
【发布时间】:2018-01-25 19:11:42
【问题描述】:

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

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

我的启动类的配置与本文 (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 引用...

同样,这是所有默认模板,但我包含 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)
    {
    }
}

【问题讨论】:

  • 在 Visual Studio 中检查输出
  • 它并不总是很明显,但是当您发布时,请确保它在“开发”环境中发布,除非您真的想在发布或生产环境中大摇大摆。
  • 谁有AKS的解决方案

标签: c# asp.net-core swagger swashbuckle


【解决方案1】:

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

例如,我在基本控制器类中有一个不明确的路由,我收到错误:“用于操作的不明确的 HTTP 方法。操作需要 Swagger 2.0 的显式 HttpMethod 绑定。”。 如果您使用基本控制器,请确保您的公共方法使用 HttpGet/HttpPost/HttpPut/HttpDelete 或 Route 属性以避免模糊路由。

然后,我也在同一个方法中定义了 HttpGet("route") 和 Route("route") 属性,这是 swagger 的最后一个问题。

【讨论】:

  • 天哪,你的第一段救了我~!我意识到没有 swagger.json 的原因是因为我的 API 控制器中有一些错误阻止了 swagger 生成 json 文件。一旦我修复了所有错误,大摇大摆的 UI 又回来了~!通过查看指向 swagger.json 的 url,它会抛出错误,这对解决问题非常有帮助!!!
  • 我遇到了同样的问题,我的删除端点之一没有完全实现并使用 Route 属性。一旦我将该端点的 Route 属性更改为 HttpDelete,错误就消失了。谢谢@Marisol
  • 此外,错误可能不会真正显示在您的浏览器中。在调试模式下运行您的应用程序,并打开所有 CLR 异常的中断。当您加载 swagger.json URL 时,将抛出异常并显示给您。这应该包含为什么没有生成 swagger.json 文件的详细信息。
【解决方案2】:

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

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 的顶部找到:

【讨论】:

  • 我实际上在 env.IsDevelopment 行上方有 app.UseSwagger,但我将它移到该部分并添加了 app.UseSwaggerUI。同样的问题。仍然没有输出。我更新了我的问题以反映新代码。
  • 现在我也被窃听了。我不知道它是否真的创建了一个文件,或者它只是动态生成 json 而没有保存它。
  • 为避免 IIS 别名出现问题,请从 URL 路径中删除 /swagger/。它应该看起来像这样:app.UseSwaggerUI(c => { c.SwaggerEndpoint("v1/swagger.json", "API name"); });
  • 谢谢@2b77bee6-5445-4c77-b1eb-4df3e5;这对我来说非常有效。
  • @Eru 很高兴这很有帮助,我刚刚将其添加为答案
【解决方案3】:

如果您的应用程序托管在 IIS/IIS Express 上,请尝试以下操作:

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

【讨论】:

    【解决方案4】:
    #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(base URL) 是应用程序别名。您需要为所有 IIS 部署保持应用程序别名(基本 URL)相同,因为 swagger 在“/swagger/v1/swagger.json”位置查找 swagger.json,但不会为应用程序别名(基本 URL)添加前缀,这就是它不起作用的原因.

    例如:

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

    【讨论】:

    • 最好使用SwaggerUIOptions.RoutePrefix 来定义webapi 前缀(使用配置中的值)而不是硬编码。
    【解决方案5】:

    我在 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");
    });
    

    【讨论】:

    • 哇,这似乎是随机的。 (它在我的情况下有效,谢谢。)
    【解决方案6】:

    您必须遵守 2 条规则:

    1. 使用显式 Http 动词(如[HttpGet("xxx")][HttpPost("xxx")]、...而不是 [Route("xxx")])装饰所有操作。
    2. 使用[NonAction] 属性装饰控制器中的公共方法。

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

    【讨论】:

    • 对我来说足够了,只需添加 [NonAction][Route("xxx")]
    • 我正在开发一个 .NET 5 控制器,使用 OnActionExecuting()/OnActionExecuted() 实现了 agaisnt IActionFilter,并将 [NonAction] 属性添加到这些方法对我来说是诀窍。跨度>
    • @MohammadBarbast 为了澄清起见,我使用了[NonAction] 而不是[NoAction](在你的第二个项目符号中),因为[NoAction]attribute 在.NET 5 中不存在(不确定你是否有错字或它曾经存在于以前的核心版本中并已更改)。
    【解决方案7】:

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

    我真的尝试了一切。因此,如果您最终遇到同样的情况,请理解问题可能是其他问题,与招摇完全无关。

    在我的情况下是 OData 异常。

    程序如下:

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

    【讨论】:

    • 同样,开发者工具显示路径指向本地主机根目录,而不是默认站点下的特定应用程序
    • 查看 Web 控制台后,我发现文档创建崩溃了,因为我有两个同名的不同条目模型。感谢您指出正确的方向。
    【解决方案8】:

    我将我的评论移至答案,因为它似乎很有帮助。


    为避免 IIS 别名出现问题,请从 URL 路径中删除 /swagger/。它应该是这样的:

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

    【讨论】:

      【解决方案9】:

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

      找出问题原因的最佳方法是从项目中排除所有控制器。然后尝试通过一次启用一个控制器或控制器中的一个或多个方法来运行应用程序,以查找有问题的控制器/控制器方法。或者您可以变得聪明并执行二进制搜索逻辑来查找禁用启用多个控制器/方法以找到有故障的控制器/方法。

      一些原因是

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

      2. 如果您不使用基于“[action]”的映射,则拥有多个具有相同 Http 属性的方法可以映射到相同的 api 调用

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

      【讨论】:

      • 我有两个 HTTPGET,不同的签名,但是一旦我删除了我的新的,我的错误就消失了。
      【解决方案10】:

      我不知道这对某人是否有用,但就我而言,问题在于名称的大小写不同。

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

      我所做的唯一一件事就是使用相同的外壳并且它有效。

      【讨论】:

      • 面临同样的问题。我发现我在声明 SwaggerDoc 和 SwaggerEndpoint 配置时使用了不匹配的版本。在我修复版本后,一切都开始正常工作了。
      【解决方案11】:

      我们在使用 Swagger 时犯的一个常见错误是为(NET ASP)两个或多个路由提供相同的名称。这导致 swagger 无法生成 JSON 文件。例如,这是错误的方式

      [HttpPost, Route("Start")]
      public async Task<TransactionResult> WipStart(BodyWipStartDTO data)
      {
          return await _wipServices.WipStart(data);
      }
      

      其他动作名称相同但动作名称不同的动作

      [HttpPost, Route("Start")]
      public async Task<TransactionResult> WipAbort(BodyWipStartDTO data)
      {
          return await _wipServices.WipAbort(data);
      }
      

      这是正确的方法

      [HttpPost, Route("Start")]
      public async Task<TransactionResult> WipStart(BodyWipStartDTO data)
      {
          return await _wipServices.WipStart(data);
      }
      
      [HttpPost, Route("Abort")]
      public async Task<TransactionResult> WipAbort(BodyWipStartDTO data)
      {
          return await _wipServices.WipAbort(data);
      }
      

      【讨论】:

      • 我的控制器没有 HttpMethod 属性(HttpGet、HttpPost 等)属性,导致招摇失败并出现 Actions require an explicit HttpMethod binding for Swagger
      【解决方案12】:

      您实际上只需要像这样删除起始反斜杠来修复招摇网址:

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

      而不是:

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

      【讨论】:

        【解决方案13】:

        我个人遇到了同样的问题,当我今天再次尝试时,我发现在 json 中的新版本(2.5.0)中,我可以看到 here 中错误的解释.

        另外一个帮助我解决它的事情是删除连接到解决方案文件夹根目录“..vs\config\applicationhost.config”中的网站的托管信息

        我删除了配置网站的元素。

                   <site name="**" id="9">
                      <application path="/" applicationPool=""></application>
                      <bindings></bindings>
                   </site>
        

        【讨论】:

          【解决方案14】:

          我在 Post 参数中使用内部类时遇到了这个问题

          [HttpPost]
          public async Task Post([FromBody] Foo value)
          {
          }
          

          Foo 在哪里

          public class Foo
          {
              public IEnumerable<Bar> Bars {get;set;}
          
              public class Bar
              {
              }
          }
          

          【讨论】:

            【解决方案15】:

            尝试遵循这些步骤,简单而干净。

            1. 检查您的控制台是否收到类似“Ambiguous HTTP method for action. Actions require an explicit HttpMethod binding for Swagger 2.0.”的错误
            2. 如果: 此错误的原因:Swagger 预期

            每个端点都应该有方法(get/post/put/delete)

            解决方案

            重新访问您的每个控制器并确保您已添加 预期的方法。

            (或者您可以在控制台错误中看到导致歧义的控制器)

            1. 如果如果您发现任何问题,请告诉我们您的问题和解决方案。

            【讨论】:

            • 在我的情况下,我错过了 put 方法 [HttpPut] 的注释,Swashbuckle 失败得很丑,并且没有给出关于错误的解释。谢谢 Unicoder。
            【解决方案16】:

            同样的问题 - 对我来说很容易解决。

            为了找到根本问题,我导航到了实际的 swagger.json 文件,它给了我真正的错误

            /swagger/v1/swagger.json
            

            此网址显示的实际错误是

            NotSupportedException: Ambiguous HTTP method for action  ... Actions require an explicit HttpMethod binding for Swagger/OpenAPI 3.0
            

            重点

            Actions require an explicit HttpMethod
            

            然后我用 [HttpGet] 修饰了我的控制器方法

            [Route("GetFlatRows")]
             [HttpGet]
             public IActionResult GetFlatRows()
             {
            

            问题已解决

            【讨论】:

              【解决方案17】:

              确保您拥有所有必需的依赖项,转到 url xxx/swagger/v1/swagger.json 您可能会发现缺少一个或多个依赖项。

              【讨论】:

              • 除此之外,如果您没有返回异常,而只是返回 500 错误,那么您可能仍然会收到隐藏的异常。在调试模式下运行时,打开所有 CLR 错误,您应该能够找到错误的详细信息。
              【解决方案18】:

              当我使用版本标头而不是 url 版本控制创建我的 api 的版本 2 时,我遇到了这个 Swagger 错误。解决方法是在版本 1 方法中添加 [Obsolete] 属性,然后使用 SwaggerGeneratorOptions 忽略 Startup -> ConfigureServices 方法中过时的 api 方法。

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

              【讨论】:

                【解决方案19】:

                我遇到了同样的问题。我使用的是像下面提到的模式那样的招摇,即“../swagger/v1/swagger.json”,因为我使用的是 IIS Express。晚于我将其更改为 “/swagger/v1/swagger.json”并清理,重建对我有用的解决方案。

                【讨论】:

                  【解决方案20】:

                  添加相对路径对我有用:

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

                  【讨论】:

                    【解决方案21】:

                    您可能忘记包含.. StartUp.cs/Configure()

                    app.UseSwagger();
                    

                    检查是否忘记包含,必须删除错误。

                    【讨论】:

                      【解决方案22】:

                      我有一个类似的问题,在我将异步版本的 API 添加到现有的 API 之后,我的 Swagger 文档损坏了。 我通过安装/重新安装来玩 Swagger DLL,最后评论新添加的 API,它工作正常。 然后我在属性中添加了不同的签名,然后宾果游戏!,它起作用了。

                      在您的情况下,您有两个具有匹配签名的 API

                      [HttpGet]
                      public IEnumerable<string> Get()
                      {
                        return new string[] { "value1", "value2" };
                      }
                      
                      // GET api/values/5
                      [HttpGet("{id}")]
                      public string Get(int id)
                      {`enter code here`
                        return "value";
                      }
                      
                      Try providing different names in attributes like
                      [HttpGet("List")]
                      public IEnumerable<string> Get()
                      {
                       return new string[] { "value1", "value2" };
                      }
                      
                      // GET api/values/5
                      [HttpGet("ListById/{id}")]
                      public string Get(int id)
                      {
                        return "value";
                      }
                      

                      这应该可以解决问题。

                      【讨论】:

                        【解决方案23】:

                        我遇到了同样的问题,并注意到我的 API 没有托管在根文件夹和虚拟目录中。 我将我的 API 移动到 IIS 的根文件夹并开始工作。

                        更多信息in this answer

                        【讨论】:

                          【解决方案24】:

                          查看 Chrome 开发者工具,有时,swagger.json 请求会抛出 http 500,这意味着您的控制器上存在一些不一致。 例如:在我的例子中,有一个“Ambiguous HTTP method for action”:

                          【讨论】:

                            【解决方案25】:

                            还有一个问题,因为我在 IIS 级别对应用程序进行版本控制,如下所示:

                            如果这样做,那么 Configure 方法中的配置应附加版本号,如下所示:

                            app.UseSwaggerUI(options =>
                            {
                                options.SwaggerEndpoint("/1.0/swagger/V1/swagger.json", "Static Data Service");
                            });
                            

                            【讨论】:

                              【解决方案26】:

                              当我尝试转到 swagger.json URL 位置时,我能够解决并理解我的问题:

                              https://localhost:XXXXX/swagger/v1/swagger.json
                              

                              页面会显示错误和找不到的原因。

                              在我的例子中,我发现我的一种方法的 XML 定义配置错误,基于它返回的错误:

                              NotSupportedException: HTTP method "GET" & path "api/Values/{id}" overloaded by actions - ...
                              ...
                              ...
                              

                              【讨论】:

                                【解决方案27】:

                                在我的情况下,问题在于方法类型,应该是 HttpPOST 但有 HttpGET 一旦我改变了它,一切都会开始工作。

                                https://c2n.me/44p7lRd.png

                                【讨论】:

                                  【解决方案28】:

                                  您应该将以下软件包安装到您的项目中。

                                  5.0.0-rc4 版本的 Swashbuckle 是最低要求。否则,它将不起作用。

                                  到目前为止,直接从 Nuget 安装它会安装不适用于 Core 3 的旧版本。

                                  我像这样在 .csproj 项目文件中插入了以下几行:

                                  <PackageReference Include="Microsoft.OpenApi" Version="1.1.4" />
                                  <PackageReference Include="Swashbuckle.AspNetCore.Swagger" Version="5.0.0-rc4" />
                                  <PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="5.0.0-rc4" />
                                  <PackageReference Include="Swashbuckle.AspNetCore.SwaggerUi" Version="5.0.0-rc4" />
                                  

                                  之后,Rebuild 会安装较新的版本。 如果没有,您也可以使用还原。

                                  在 Startup.cs 中,您应该像这样配置 Swashbuckle:

                                   // This method gets called by the runtime. Use this method to add services to the container.
                                      public void ConfigureServices(IServiceCollection services)
                                      {
                                          services.AddControllers();
                                  
                                              // Register the Swagger generator, defining 1 or more Swagger documents
                                              services.AddSwaggerGen(c =>
                                              {
                                                  c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
                                              });
                                  
                                          services.AddMvc();
                                      }
                                  

                                   

                                  // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
                                      public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
                                      {
                                          if (env.IsDevelopment())
                                          {
                                              app.UseDeveloperExceptionPage();
                                          }
                                  
                                          app.UseHttpsRedirection();
                                  
                                          // Enable middleware to serve generated Swagger as a JSON endpoint.
                                          app.UseSwagger();
                                  
                                          // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
                                          // specifying the Swagger JSON endpoint.
                                          app.UseSwaggerUI(c =>
                                          {
                                              c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
                                              //c.RoutePrefix = String.Empty;
                                          });
                                  
                                          app.UseRouting();
                                  
                                          app.UseAuthorization();
                                  
                                          app.UseEndpoints(endpoints =>
                                          {
                                              endpoints.MapControllers();
                                          });
                                      }
                                  

                                  只需转到“https://localhost:5001/swagger/index.html”,您就会看到 Swagger UI。 (5001是我的本地端口,你应该用你的改变它)

                                  我花了一点时间才弄明白。

                                  我希望它会帮助其他人:)

                                  【讨论】:

                                    【解决方案29】:

                                    答案:

                                    If using directories or application  with IIS or a reverse proxy,<br/> set the Swagger endpoint to a relative path using the ./ prefix. For example,<br/> ./swagger/v1/swagger.json. Using /swagger/v1/swagger.json instructs the app to<br/>look for the JSON file at the true root of the URL (plus the route prefix, if used). For example, use http://localhost:<br/><br/><port>/<route_prefix>/swagger/v1/swagger.json instead of http://localhost:<br/><port>/<virtual_directory>/<route_prefix>/swagger/v1/swagger.json.<br/>
                                    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");
                                    //Add dot in front of swagger path so that it takes relative path in server
                                    c.SwaggerEndpoint("./swagger/v1/swagger.json", "MyAPI V1");
                                        });
                                    }
                                    
                                    [Detail description of the swagger integration to web api core 3.0][1]
                                    
                                    
                                      [1]: https://docs.microsoft.com/en-us/aspnet/core/tutorials/getting-started-with-swashbuckle?view=aspnetcore-3.1&tabs=visual-studio
                                    

                                    【讨论】:

                                      【解决方案30】:

                                      我遇到了一个愚蠢的问题,我在 AddSwaggerGen 方法中有一个大写的 v,在 c.SwaggerEndpoint 中有一个小写的 v。

                                      它似乎区分大小写。

                                      【讨论】:

                                        猜你喜欢
                                        • 2017-04-16
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 2019-02-15
                                        • 2019-11-27
                                        • 2021-07-14
                                        • 1970-01-01
                                        • 2017-07-11
                                        相关资源
                                        最近更新 更多