Swashbuckle/Swagger + ASP.Net 核心:"Failed to load API definition"

Swashbuckle/Swagger + ASP.Net Core: "Failed to load API definition"

我开发了一个 ASP.NET Core 2 应用程序并包含了 Swagger。一切正常,直到我引入了一个没有明确定义 HTTP 操作的方法:

public class ErrorController : Controller
{
    [Route("/error")]
    public IActionResult Index()
    {
        return StatusCode(500, new Error("Internal error."));
    }
}

当我用这种方法启动应用程序时,出现以下消息:

Failed to load API definition.

Errors
Fetch error Internal Server Error /swagger/v1/swagger.json

只要我明确设置例如[HttpGet] 错误消失。这个问题是,我需要这个方法来触发所有可能的 HTTP 操作。 当然,我可以明确指定所有操作,但我感觉 Swagger 应该能够正确处理这个问题。

为什么 Swagger 会这样?

有没有我可以使用的配置?

选项 ResolveConflictingActions 应该适用于这种情况...

这是实际错误:

System.NotSupportedException: Ambiguous HTTP method for action

来自: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/86cc761bc4f5dda796f80ad8dfd8bc205542a6f6/src/Swashbuckle.AspNetCore.SwaggerGen/Generator/SwaggerGenerator.cs#L90

我认为这是一个错误,如果你真的感兴趣,你应该向项目报告它

我不知道这个问题是否已经解决,但是您可以解决这个问题的一种方法是用以下方法装饰方法:

[ApiExplorerSettings(IgnoreApi = true)]

这将确保有问题的方法被 Swagger 忽略。

为每个 Action 方法添加 Httpxxx([HttpGet], [HttpPost], ...) 属性,或 [ApiExplorerSettings(IgnoreApi = true)]

我正在删除未使用的 class 上的 TypeLoadException。我的解决方法是删除 bin/obj/Debug 文件夹内容。清洁解决方案 + 重建解决方案没有为我解决。

如果有 public 方法不是控制器中的操作,Swagger 也会抛出相同的异常。解决方法是使它们全部 protectedprivate 或如上所述添加属性 [ApiExplorerSettings(IgnoreApi = true)].

我也遇到了这个错误,因为我创建了一个控制器,其中包含 [Route("api/[controller]")]。放好后,错误消失了。

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

在 ASP.NET Core 中,如果有控制器端点,例如:

[Route("images")]
[HttpGet("{id}")]

这也可能因获取失败而失败。解决方案是有类似

的东西
[HttpGet("images/{id}")]

HttpPost 也是如此。

另一个可能的问题是端点需要从域根开始。

我有:

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

我必须使用:

 app.UseSwaggerUI(c=>
{
     c.SwaggerEndpoint("/myApi/swagger/v1/swagger.json", "V1 Docs");

});

我的错误原因是同一个 url 名字,

 [HttpGet("get/LeaveCommand/{id}")]

我使用相同的 url 并且 swagger 无法获得它们

 [HttpGet("get/LeaveCommand/{id}")]

您可以简单地查看 Output window 中的日志。在我的案例中可以看到实际的错误,我错过了在方法之上添加 HTTP 操作

除了 Helder Sepulvedas 的回答和本 github 期的 'Monte-Christos' 回答之外 - Actions require unique method/path combination for Swagger

I found the place to configure ResolveConflictingActions in ASP.NET Core apps. In your Setup class, add this to the ConfigureServices() method:

services.AddSwaggerGen(c => 
  { 
    other configs...;
    c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
  });

这对我有用!

仔细检查,如果您在同一控制器中使用了相同的 url 名称。我的代码发生了

对我有用的是将 [NonAction] 属性添加到 public 方法,这些方法在我的控制器包装器中不是 API 调用。

我的情况是 Newtonsoft.Json。但问题是我没有使用它。其中一个包可能依赖于它,但我没有时间检查。

所以只需检查输出面板即可解决相关问题。

在我的例子中,我像使用 .net 代码一样使用此代码

[ActionName("Login")]
[HttpPost]

现在我将其更改为在 net core web 上使用 api

[HttpPost("Login")]

而且效果不错

我遇到了同样的问题。在我的例子中,我所有的控制器都继承自 BaseController。在此基础 class 中,我得到了一个 public 操作,其中 returns UserId 根据 Claims。我在此操作的顶部设置了 [NonAction] 属性。

[ApiController]
[ApiResultFilter]
[Route("api/[controller]")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]

public class BaseController : ControllerBase
{

    [NonAction]
    public int GetCurrentUserId()
    {
        return int.Parse(this.User.Claims.First(p => p.Type == ClaimTypes.NameIdentifier).Value);
    }
}

与其盲目猜测可能是什么问题,不如导航至

http:///swagger/v1/swagger.json

在我的例子中,这可以通过使用 c.CustomSchemaIds(x => x.FullName);

这是一个糟糕的解决方法,但对于有需要的人来说可能是一个快速解决方法。我的解决方案是重命名并阐明这些端点的路径

我也遇到了这个问题。我检查并应用了 swagger 配置的所有解决方案,但问题仍然存在。 最后,我检查了输出面板,问题是因为 [DefaultValue("SYSDATETIMEOFFSET()")].

答案在这里:检查输出面板,你会找到答案

如果您的模型(请求或响应)属性类型 inherits/implements 类型类似于 System.ComponentModel(或其他类型),这将引发错误

"The JSON property 'item' is defined multiple times on type"...

尝试使用 Newtonsoft.Json

[JsonIgnore] 属性忽略此 属性

在我的例子中,我有一个 getter 类型 DataTable

在启动文件中,您需要确保添加

services.AddSwaggerDocument();

在您添加之前

app.UseOpenApi();
app.UseSwaggerUi3();

否则会导致此错误

Fetch error undefined /swagger/{documentName}/swagger.json

对于核心 3,我遇到了同样的问题,并且很困惑问题出在斜杠中。

配置为:

services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "my-API", Version = "v1" });
            });

这个 swagger 端点抛出了 TS 的消息:

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

最后我成功删除了 URL:

中的第一个斜线
app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("v1/swagger.json", "my-API v1");
            });

对我来说,问题是在 MapControllers 中间件之后注册 swagger。一旦我在它工作之前移动了。

对我来说这是一个非常简单的问题,我有 3 个 [HttpGet] 方法,结果我需要将“createOrder”方法更改为 [HttpPost]

        [HttpGet]
        public async Task<ActionResult<List<Order>>> GetOrders()
        {
            return await _context.Orders.Include(o => o.OrderItems).Where(x => x.BuyerId == User.Identity.Name).ToListAsync();
        }

        [HttpGet("{id}", Name = "GetOrder")]
        public async Task<ActionResult<Order>> GetOrder(int id)
        {
            return await _context.Orders.Include(x => x.OrderItems).Where(x => x.BuyerId == User.Identity.Name && x.Id == id).FirstOrDefaultAsync();
        }

        [HttpPost]
        public async Task<ActionResult<int>> CreateOrder(CreateOrderDto orderDto)
        {
            var basket = await _context.Baskets.RetrieveBasketWithItems(User.Identity.Name).FirstOrDefaultAsync();
            var items = new List<OrderItem>();
}

猜猜看...开始收到此错误页面“Failed to load API definition”:

通过查看应用程序的控制台或 Visual Studio 中的输出 window,它告诉我以下内容:

我在网络上添加了一个名为 Client 的 public 方法 API BaseControllerSwagger 认为它应该包含在 API.

解决问题:将该方法标记为protected:

对我来说,通过添加 HttpGet 属性并删除索引方法解决了这个问题。

我的问题是由 lazy/frustrated 重构引起的,当 运行 API 处于调试器模式时,我能够通过阅读调试控制台来确定问题。

由于糟糕的重构,我最终得到了两个同名模型,Swagger 变得很困惑。

我有类似的东西:

PROJECT
├───Auth
│       AutheController.cs
│       UserDto.cs
│
└───Controllers
    │   MyContrller.cs
    │
    └───Models
            UserDto.cs

拥有两个 UserDto 模型是让 Swagger 感到困惑的地方。清理它解决了问题。