调试Swashbuckle错误 - 加载API定义失败

22
有没有办法在Swashbuckle/Swagger错误时获取堆栈跟踪或内部异常?某个时刻,它停止工作了。我不确定是在升级从.Net Core 2.0到2.1时停止的,但我相当确定在那之后它仍然有效。当我导航到myapidomain/swagger/index.html时,我得到了这个错误:enter image description here 这并不是很有用。它在两周前还在工作...我没有更改任何Swagger配置。它跟以前一样:
public void ConfigureServices(IServiceCollection services)
{
    ...
     services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new Info
            {
                Version = "v1",
                Title = "My.API",
                Description = "Test"
            });
        });   
}


public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
        app.UseDeveloperExceptionPage();
    else
        app.UseHsts();

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

我正在使用 Swashbuckle.AspNetCore 3.0.0 开发 ASP.Net Core 2.1 Web API。


4
打开 swagger/v1/swagger.json 文件会得到什么? - Helder Sepulveda
谢谢Helder,抱歉现在才看到你的评论。是的,打开那个文件帮助我找出了问题所在。 - Fabricio Rodriguez
我遇到了一个类似的问题(https://dev59.com/4Lfna4cB1Zd3GeqPv5x2),但是使用的是最新版本的ASP.Net Swashbuckle 5.6.0。失败看起来非常不同,而且我从请求中没有得到任何有用的调试信息。我想知道为什么你的Swashbuckle表现如此不同。 - nbrosz
4个回答

43
同意UI上的信息对于调试来说并不有用(加载API定义失败/获取错误等),但是完整的异常跟踪可以通过打开浏览器的调试工具(例如Chrome上的F12),刷新您的/swagger端点,然后检查swagger.json负载来获取(这是一个XHR请求,将以500状态码失败)。
(我建议在一个大项目中,您可以将链接添加到书签中,这样将来您可以直接访问json文件,例如https://MyHost/swagger/v1/swagger.json)
例如,在下面的虚构错误中,我在两个方法之间复制了相同的路由:
[HttpGet]
[Route("parseenum")]
public ActionResult CheckEnum([FromQuery] MyEnum someEnum)
...

[HttpGet]
[Route("parseenum")]
public ActionResult CheckEnum2([FromQuery] MyEnum someEnum)
...

产生错误的原因是:

SwaggerError

你现在应该能够找到并修复它了。

3
谢谢 Stuart!我按照你的指示进行操作,并找到了问题的根源:"System.InvalidOperationException: Conflicting schemaIds: Identical schemaIds detected for types PropWorx.API.ModelsShared.User and PropWorx.API.Models.User. See config settings - "CustomSchemaIds" for a workaround" - Fabricio Rodriguez
1
这在Swagger 8.3.20.403上无法运行。不再有swagger.json文件。已下载一个V1条目,但在预览选项卡中未提供任何信息。 - Dave de Jong
1
这个非常好用,我已经寻找了一段时间快速简单地调试非类型安全问题的方法。 - Matthew Flynn

1
如果您的API中有两个或更多相同的[HttpGet],则Swagger无法正常工作。您应该具体指定[HttpGet],[HttpGet("{id}")]
  [HttpGet]
`[HttpGet ("{id}")]`

0
今天我遇到了这个问题,尝试了很多方法来解决它。你必须在C#控制器代码中删除所有[Route]标记之前的[http]标记,就像这段代码一样: 例如:
[Route("~/api/getAll")]
[HttpGet]
public ActionResult<List<asteriksModel>>GetAll()
{
    return _context.asterList.ToList();
}

你的路由代码必须像这样

[HttpGet]
public ActionResult<List<asteriksModel>>GetAll()
{
    return _context.asterList.ToList();
}

在我的项目中它运行良好。


是的,Swagger使用控制器默认路由,所有程序员都需要自己路由API,因此Swagger无法找到我们的路由并使用默认路由。为了使用它们,我们必须从[http..]的顶部或旁边(如[HttpGet,[Route("...")]])删除所有[Route]。这样做可以正常工作,不需要它们。 - MsDeveloper
很不幸,我忘了告诉你这一点,你必须像这样设置你的API路由: [Route("api/[controller]")] - MsDeveloper

0
我发现 SwaggerFunctions 需要匿名才能完成 Swagger/UI。
public static class SwaggerFunctions
{
    [SwaggerIgnore]
    [FunctionName("Swagger")]
    public static Task<HttpResponseMessage> Swagger(
        [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "swagger/json")]
    HttpRequestMessage req,
        [SwashBuckleClient] ISwashBuckleClient swashBuckleClient)
    {
        return Task.FromResult(swashBuckleClient.CreateSwaggerDocumentResponse(req));
    }

    [SwaggerIgnore]
    [FunctionName("SwaggerUi")]
    public static Task<HttpResponseMessage> SwaggerUi(
        [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "swagger/ui")]
    HttpRequestMessage req,
        [SwashBuckleClient] ISwashBuckleClient swashBuckleClient)
    {
        return Task.FromResult(swashBuckleClient.CreateSwaggerUIResponse(req, "swagger/json"));
    }
}

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