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
我认为这是一个错误,如果你真的感兴趣,你应该向项目报告它
我不知道这个问题是否已经解决,但是您可以解决这个问题的一种方法是用以下方法装饰方法:
[ApiExplorerSettings(IgnoreApi = true)]
这将确保有问题的方法被 Swagger 忽略。
为每个 Action 方法添加 Httpxxx([HttpGet]
, [HttpPost]
, ...) 属性,或 [ApiExplorerSettings(IgnoreApi = true)]
我正在删除未使用的 class 上的 TypeLoadException
。我的解决方法是删除 bin/obj/Debug 文件夹内容。清洁解决方案 + 重建解决方案没有为我解决。
如果有 public 方法不是控制器中的操作,Swagger 也会抛出相同的异常。解决方法是使它们全部 protected
或 private
或如上所述添加属性 [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 BaseController
和 Swagger 认为它应该包含在 API.
中
解决问题:将该方法标记为protected:
对我来说,通过添加 HttpGet 属性并删除索引方法解决了这个问题。
我的问题是由 lazy/frustrated 重构引起的,当 运行 API 处于调试器模式时,我能够通过阅读调试控制台来确定问题。
由于糟糕的重构,我最终得到了两个同名模型,Swagger 变得很困惑。
我有类似的东西:
PROJECT
├───Auth
│ AutheController.cs
│ UserDto.cs
│
└───Controllers
│ MyContrller.cs
│
└───Models
UserDto.cs
拥有两个 UserDto
模型是让 Swagger 感到困惑的地方。清理它解决了问题。
我开发了一个 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
我认为这是一个错误,如果你真的感兴趣,你应该向项目报告它
我不知道这个问题是否已经解决,但是您可以解决这个问题的一种方法是用以下方法装饰方法:
[ApiExplorerSettings(IgnoreApi = true)]
这将确保有问题的方法被 Swagger 忽略。
为每个 Action 方法添加 Httpxxx([HttpGet]
, [HttpPost]
, ...) 属性,或 [ApiExplorerSettings(IgnoreApi = true)]
我正在删除未使用的 class 上的 TypeLoadException
。我的解决方法是删除 bin/obj/Debug 文件夹内容。清洁解决方案 + 重建解决方案没有为我解决。
如果有 public 方法不是控制器中的操作,Swagger 也会抛出相同的异常。解决方法是使它们全部 protected
或 private
或如上所述添加属性 [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 BaseController
和 Swagger 认为它应该包含在 API.
解决问题:将该方法标记为protected:
对我来说,通过添加 HttpGet 属性并删除索引方法解决了这个问题。
我的问题是由 lazy/frustrated 重构引起的,当 运行 API 处于调试器模式时,我能够通过阅读调试控制台来确定问题。
由于糟糕的重构,我最终得到了两个同名模型,Swagger 变得很困惑。
我有类似的东西:
PROJECT
├───Auth
│ AutheController.cs
│ UserDto.cs
│
└───Controllers
│ MyContrller.cs
│
└───Models
UserDto.cs
拥有两个 UserDto
模型是让 Swagger 感到困惑的地方。清理它解决了问题。