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

时间:2018-01-25 19:11:43

标签: asp.net-core swagger swashbuckle

我无法获取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引用...

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)
    {
    }
}

35 个答案:

答案 0 :(得分:22)

我相信你在配置上错过了这两行:

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

要访问Swagger UI,网址应为:http://localhost:XXXX/swagger/

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

enter image description here

答案 1 :(得分:14)

#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部署保持Application Alias(基本URL)相同,因为swagger在“ /swagger/v1/swagger.json”位置查找swagger.json,但不会在应用程序Alias(基本URL)之前添加前缀,这就是它无法正常工作的原因

例如:

  

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

答案 2 :(得分:9)

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


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

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

答案 3 :(得分:9)

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

例如,我在基本控制器类中存在一条歧义路由,并且收到错误消息:“歧义HTTP方法用于操作。行为需要Swagger 2.0的显式HttpMethod绑定。” 如果您使用基本控制器,请确保您的公共方法使用HttpGet / HttpPost / HttpPut / HttpDelete OR Route属性来避免路由不明确。

然后,我也用相同的方法定义了HttpGet(“ route”)和Route(“ route”)属性,这是大摇大摆的最后一个问题。

答案 4 :(得分:6)

我碰到了类似但又不完全相同的问题。希望这可以帮助其他人。

我正在使用自定义文档标题,并且没有更改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");
        });

答案 5 :(得分:5)

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

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

答案 6 :(得分:4)

您必须遵守2条规则:

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

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

答案 7 :(得分:3)

如果您在控制器中无法映射到唯一的URL,则会收到此错误。

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

某些原因是

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

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

答案 8 :(得分:2)

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

要找到潜在的问题,我导航到了实际的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()
 {

问题已解决

答案 9 :(得分:2)

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

服务配置中的

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

我唯一要做的就是使用相同的大小写,并且可以正常工作。

version name with capital V

答案 10 :(得分:1)

实际上,您只需要通过删除开头的反斜杠来修改swagger网址,如下所示:

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

而不是:

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

答案 11 :(得分:1)

添加相对路径对我有用:

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

答案 12 :(得分:1)

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

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

Foo在哪里

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

    public class Bar
    {
    }
}

答案 13 :(得分:1)

尝试轻松,清洁地执行以下步骤。

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

每个端点都应具有方法(获取/发布/放入/删除)

。      解决方案

  

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

(或者您可以在控制台错误中看到哪个控制器引起歧义)

  1. 如果如果发现任何问题,请告知我们。

答案 14 :(得分:1)

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

我确实尝试了所有方法。因此,如果您遇到同样的情况,请您理解这个问题可能是另外一些问题,与大张旗鼓完全无关。

在我的情况下是OData异常。

导航到localhost:xxxx / swagger打开开发人员工具后,单击控制台上的错误,您将看到导致问题的内部异常。

希望有帮助

答案 15 :(得分:1)

就个人而言,我遇到了同样的问题,当我在新版本(2.5.0)中找到json后的一段时间后我今天再次尝试时,我可以看到here中的错误的解释{3}}

另一件帮我解决的问题是删除连接到网站的托管信息,该信息位于解决方案文件夹根目录下的“..vs \ config \ applicationhost.config”中

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

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

答案 16 :(得分:0)

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

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

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

就我而言,我发现其中一个方法由于返回的错误而配置错误的XML定义:

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

答案 17 :(得分:0)

// Enable middleware to serve generated Swagger as a JSON endpoint.

app.UseSwagger(c =>
{
    c.SerializeAsV2 = true;
});

// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "API Name");
});

答案 18 :(得分:0)

您可能会忘记添加。.StartUp.cs / Configure()

app.UseSwagger();

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

答案 19 :(得分:0)

我有一个类似的问题,在将异步版本的API添加到现有的API之后,我的Swagger文档破裂了。 我通过安装/重新安装来解决Swagger DLL的问题,最后对新添加的API进行了注释,然后它起作用了。 然后我在属性中添加了不同的签名,然后是bingo !,它起作用了。

在您的情况下,您有两个具有匹配签名的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";
}

这应该可以解决问题。

答案 20 :(得分:0)

就我而言,我忘记为方法设置public访问修饰符!

答案 21 :(得分:0)

我有相同的错误,但是由于问题不同,我正在使用引起此问题的第3方库,因此我无需将此库公开,因此我使用了以下发布的解决方案{ {3}}。

使用以下内容在某个地方创建类ApiExplorerIgnores

public class ApiExplorerIgnores : IActionModelConvention
{
    public void Apply(ActionModel action)
    {
        if (action.Controller.ControllerName.Equals("ImportExport"))
            action.ApiExplorer.IsVisible = false;
    }
}

在Startup.cs中的方法ConfigureServices中添加以下代码

services.AddMvc(c => c.Conventions.Add(new ApiExplorerIgnores()))

这将读取该控制器中的所有方法,您也可以使用特定级别,例如方法名称左右,也可以仅删除一个方法,等等,

答案 22 :(得分:0)

根据Microsoft: 要在应用程序的根目录(http://localhost:/)中提供Swagger UI,请将RoutePrefix属性设置为空字符串:

app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
c.RoutePrefix = string.Empty;
});

答案 23 :(得分:0)

对于简单的 API 文档,请使用以下约定。

ConfigureServices方法中

        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new OpenApiInfo { Title = "My Test API", Version = "1.0.0.0" });
            c.OperationFilter<SwaggerAuthorizationOperationFilter>();
            c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
            {
                Description = "Enter the request header in the following box to add Jwt To grant authorization Token: Bearer Token",
                Name = "Authorization",
                In = ParameterLocation.Header,
                Type = SecuritySchemeType.ApiKey,
                BearerFormat = "JWT",
                Scheme = "Bearer"
            });
            //c.SchemaFilter<SwaggerExcludeSchemaFilter>();
            c.AddSecurityRequirement(new OpenApiSecurityRequirement
                {
                {
                    new OpenApiSecurityScheme
                    {
                        Reference = new OpenApiReference {
                            Type = ReferenceType.SecurityScheme,
                            Id = "Bearer"
                        }
                    },
                    new string[] { }
                }
                });
        });

Configure方法中

        app.UseSwagger();
        app.UseSwaggerUI(c =>
            {
                c.DefaultModelExpandDepth(2);
                c.DefaultModelsExpandDepth(-1);
                c.DisplayOperationId();
                c.DisplayRequestDuration();
                c.EnableDeepLinking();
                c.EnableFilter();
                c.ShowExtensions();
                c.EnableValidator();
            });

        // 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 Test API");
            c.RoutePrefix = "";
            c.DocumentTitle = "My Test API Docs";                
        });

请注意以下 2 行按顺序构成了这两种方法。

c.SwaggerDoc("v1", new OpenApiInfo { Title = "My Test API", Version = "1.0.0.0" });

c.SwaggerEndpoint("/swagger/v1/swagger.json", "My Test API");

所以无论你放什么,而不是应该匹配的 v1

答案 24 :(得分:0)

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

它似乎区分大小写。

答案 25 :(得分:0)

答案:

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

答案 26 :(得分:0)

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

最低为

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是我的本地端口,您应该用自己的端口进行更改)

我花了一些时间才弄清楚。

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

答案 27 :(得分:0)

我有同样的问题。我使用了如下所述的模式,即“ ../swagger/v1/swagger.json”,因为我使用的是IIS Express。后来我将其更改为 “ /swagger/v1/swagger.json”并清理,重新生成对我有用的解决方案。

Swagger Enable UI

答案 28 :(得分:0)

就我而言,问题出在方法类型上,应该是HttpPOST,但是有HttpGET 一旦我改变了一切,一切就开始起作用。

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

答案 29 :(得分:0)

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

enter image description here

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

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

答案 30 :(得分:0)

看看Chrome开发者工具,有时,swagger.json请求抛出http 500,女巫意味着您的控制器存在一些不一致之处。 例如:就我而言,有一个“歧义HTTP操作方法”:

enter image description here

答案 31 :(得分:0)

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

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

答案 32 :(得分:0)

使用Swagger时,我们经常犯的一个错误是为(NET ASP)两个或多个路由赋予相同的名称。这会导致招摇无法生成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);
}

答案 33 :(得分:0)

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

enter image description here

答案 34 :(得分:0)

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

更多信息in this answer