Swagger .NET Core API: Action 方法的 HTTP 方法不明确错误

65

使用.NET Core 2 API实现Swashbuckle/Swagger时,访问swagger.json时出现500错误:

NotSupportedException: 操作存在模棱两可的HTTP方法 - EBisAPI.Controllers._class.HandleError(EBisAPI)。操作要求Swagger有明确的HttpMethod绑定

我已经查看了所有控制器并在每个控制器的公共方法上看到了明确的路由。有没有办法确定哪个方法会导致模糊路由错误?

9个回答

93
这可能是由于在控制器中声明了一个公共方法,但没有REST属性导致的。将该方法更改为受保护的方法可能会解决此问题。 我以前见过这种错误,并且通常错误消息会指向罪魁祸首:EBisAPI.Controllers._class.HandleError。我猜HandleError是您基类中的一个公共方法,对吧?将其更改为protected,然后再试一次。当然,这只是一种可能的解决方案。如果在错误消息中提到的方法是接口实现的一部分,则它无效,您需要查看其他解决方案之一。

2
哇 - 不确定我是怎么错过了,即使复制并粘贴错误 - 谢谢。 - sammarcow
1
@devC:当然,你的端点方法必须是公共的。在sammarcows的情况下,这是一个帮助方法,不打算由控制器公开。 - jps
没错,在我的情况下,我有一个额外的[Route]注释,这导致了Swagger失败。我已经解决了它。 - devC
1
我的问题是因为我不小心注释掉了我的 [HttpGet] 属性。哎呀。 - mwilson
将过滤器方法更改为 protected 后,出现以下错误: 严重程度 代码 描述 项目 文件 行 抑制状态 错误 CS0737 “OrderController”未实现接口成员“IActionFilter.OnActionExecuting(ActionExecutingContext)”。“OrderController.OnActionExecuting(ActionExecutingContext)”无法实现接口成员,因为它不是公共的。 - Sujoy
显示剩余5条评论

35

1
是的!我不得不在我的某个路由中添加 IgnoreApi = true。然后 Swagger UI 就很高兴了。 - MTMDev
是的,当然!感谢您的观察! - ditao

26

清晰的方法是使用数据注释[NonAction]来将您的方法设置为受保护状态。


IActionFilter 方法更改为 protected 导致以下错误:Severity Code Description Project File Line Suppression State Error CS0737 'OrderController' does not implement interface member 'IActionFilter.OnActionExecuting(ActionExecutingContext)'. 'OrderController.OnActionExecuting(ActionExecutingContext)' cannot implement an interface member because it is not public.然而,**[NonAction]** 解决了问题。 - Sujoy
当我在 [Route("error")] [NonAction] [AllowAnonymous] public IActionResult Error() { ... } 中添加 [NonAction] 后,我收到了 404 错误。 ASP.NET Core 找不到我的 /error 端点。我投反对票。 - Exegesis

20

我通过为错误中提到的方法使用正确的HTTP属性进行修饰来解决了这个错误。例如:[HttpGet]

这段代码会抛出错误:

public object Get()
{
    MongoDbContext dbContext = new MongoDbContext();
    return new {
        API = true,
        Database = dbContext.Status()
    };
}

这段代码可以工作:

[HttpGet]
public object Get()
{
    MongoDbContext dbContext = new MongoDbContext();
    return new {
        API = true,
        Database = dbContext.Status()
    };
}

15

正如我在"Swashbuckle not creating swagger.json file"中提到的:

  1. 为所有操作显式地添加Http方法装饰器,例如[HttpGet("xxx")][HttpPost("xxx")]等,而不是使用[Route("xxx")]
  2. 在控制器中,将公共方法装饰为[NonAction]属性。

2
为什么你想在控制器中拥有公共方法却没有对应的操作呢? - Jorn.Beyers
为了代码重用,也许您想要一个在多个操作中被调用且不在其他控制器或其他地方使用的方法。@jorn.Beyers - Mohammad Barbast
1
如果它不在其他控制器或其他地方使用,你将其标记为私有(private)吗? - Jorn.Beyers
是的,您也可以使用private。但是如果您使用公共方法而不将其用作操作,则必须使用[NoAction]进行装饰。这种情况很少见,但在我尚未遇到的特殊情况下可能需要它(例如,使用反射反射公共方法或...)。@Jorn.Beyers - Mohammad Barbast
1
小错误,应该是[NonAction]。 - mishal153

2

我尝试了不同的解决方案,但对我有效的是按照上述方式在属性中添加路由。例如:[HttpPost("yourRoute/create")] 其中一个问题是我有2个GET方法,所以我改变了它们的名称,并像我说的那样在属性中添加了路由。


0
我曾经遇到过同样的问题,原因是我重写了Ok()方法并返回了一个OkObjectResult。解决方法是将其从public更改为protected。

0

我曾经遇到过同样的问题。对我来说,错误是默认情况下WeatherForecastController或任何其他类都继承自ControllerBase类。但是当我创建一个新的控制器时,它继承自Controller类。

因此,ControllerBaseController类之间的冲突导致了这个问题。

然后,将新控制器从ControllerBase类继承解决了我的问题。

您不能同时从ControllerBaseController继承。


0
在我的情况下,我的 Rest Controller 中有一个公共方法,它被 HttpGet() 和 Route() 装饰。我移除了 Route(),这样就解决了问题,Swagger 在 UI 中生成了正确的路由。

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