63

Implementing Swashbuckle/Swagger with .net Core 2 API I am now receiving the 500 error when accessing swagger.json:

NotSupportedException: Ambiguous HTTP method for action - EBisAPI.Controllers._class.HandleError (EBisAPI). Actions require an explicit HttpMethod binding for Swagger

I have gone through all the controllers and see explicit routing on all the public methods of each controller. Is there a way to determine which method is throwing the ambiguous routing error?

Michael Freidgeim
  • 26,542
  • 16
  • 152
  • 170
sammarcow
  • 2,736
  • 2
  • 28
  • 56

9 Answers9

92

This can occur when a method is declared public in a controller, but without REST attributes. Changing the method to protected may address the issue.

I have seen this kind of error before and usually the error message points to the culprit: EBisAPI.Controllers._class.HandleError

I guess HandleError is a public method in your base class, right? Change it to protected and try again.

This is of course only one possible solution. If the method which is mentioned in the error message is part of an interface implementation, it doesn't work and you need to look at one of the other solutions.

jps
  • 20,041
  • 15
  • 75
  • 79
  • 2
    wow - not sure how i missed that even copying ans pasting the error - thanks – sammarcow Dec 15 '17 at 16:33
  • I face the similar issue but when I convert the API endpoint to a protected method, it issues a 404 – devC Jan 17 '18 at 09:47
  • 1
    @devC : of course your endpoint methods must be public. In sammarcows case it's a helper method which is not intended to be exposed by the controller. – jps Jan 17 '18 at 11:30
  • Right, and in my case, I had an additional [Route] annotation, which was causing the swagger to fail. I resolved it. – devC Jan 17 '18 at 15:56
  • 1
    My issue was because I accidentally commented out my `[HttpGet]` attribute. Oops. – mwilson May 16 '19 at 02:04
  • Any clues on how to fix this error when the method exists in a third party DLL? – RugerSR9 Jul 05 '19 at 19:17
  • Thanks you very much – HOÀNG LONG Jan 05 '21 at 16:02
  • ON changing the filter method to protected I get the following error: `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.` – Sujoy Sep 07 '21 at 07:49
  • @Sujoy as mentioned already in the first sentence, setting the method to protected 'may' help. Of course, it doesn't work if the method implements an interface. It's certainly not the universal solution for all cases. – jps Sep 09 '21 at 10:42
  • When I add `protected` to `[Route("error")] [AllowAnonymous] protected IActionResult Error() { ... }` I get back a 404. ASP.NET Core cannot find my `/error` endpoint. Voting down. – Exegesis May 06 '22 at 02:03
32

Similar to totonho's answer you can use

[ApiExplorerSettings(IgnoreApi=true)]

(From https://github.com/domaindrivendev/Swashbuckle/issues/153 )

Roman Marusyk
  • 23,328
  • 24
  • 73
  • 116
Michael Freidgeim
  • 26,542
  • 16
  • 152
  • 170
25

The Clean way could be using data annotation [NonAction] instead to set your method as protected.

ealvess
  • 519
  • 5
  • 12
  • Changing the `IActionFilter` methods to protected was causing the following error: `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.` However **`[NonAction]`** did the trick – Sujoy Sep 07 '21 at 07:53
  • When I add `[NonAction]` to `[Route("error")] [NonAction] [AllowAnonymous] public IActionResult Error() { ... }` I get back a 404. ASP.NET Core cannot find my `/error` endpoint. Voting down. – Exegesis May 06 '22 at 02:02
19

I solved this error by decorating the method mentioned in the error with the correct HTTP attribute. For exemple: [HttpGet]

This code throws error:

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

This code works:

[HttpGet]
public object Get()
{
    MongoDbContext dbContext = new MongoDbContext();
    return new {
        API = true,
        Database = dbContext.Status()
    };
}
Guilherme Ferreira
  • 1,503
  • 2
  • 18
  • 31
14

As i mentioned at "Swashbuckle not creating swagger.json file" :

  1. Decorate all actions with explicit Http Methods like[HttpGet("xxx")],[HttpPost("xxx")] or ... instead of [Route("xxx")].
  2. Decorate public methods in controllers with [NonAction] Attribute.
Mohammad Barbast
  • 1,753
  • 3
  • 17
  • 28
  • 2
    why would you want to have public methods in controllers without having an action? – Jorn.Beyers Jun 11 '19 at 10:32
  • For code reuse, maybe you would want to have a method that is called multiple times in actions and is not used in other controllers or other places. @jorn.Beyers – Mohammad Barbast Jun 11 '19 at 15:33
  • 1
    if it is not used in other controller or other places, you mark it as private? – Jorn.Beyers Jun 12 '19 at 07:30
  • Yes you can also use private. However if you use public method that is not used as an action, we have to decorate it with `[NoAction]`. This Case is rarely used but maybe you need it in special situations that I haven't encountered yet. (like. using reflection to reflect over public methods or ... ).@Jorn.Beyers – Mohammad Barbast Jun 12 '19 at 09:47
  • 1
    minor typo. it should be [NonAction]. (unable to edit the answer as its less than 6 character change) – mishal153 Mar 30 '23 at 12:37
2

I tried different solutions but what it worked for me was adding the route inside the attributes as stated above. I.E: [HttpPost("yourRoute/create")] one of the issues was that I have 2 get methods so I changed their names and added the route to the attributes as I said.

Dharman
  • 30,962
  • 25
  • 85
  • 135
0

I Had the same problem, and was because i have done the override of the Ok() method ,returning an OkObjectResult. The solution was change it from public to protected

0

I was facing the same issue. For me the mistake was by default WeatherForecastController or any other class was inheriting from ControllerBase class. But when I created a new one, it inherited from Controller class.

So this conflicts between ControllerBase and Controller class was causing the issue.

Then inheriting the new Controller from ControllerBase class fixed the issue for me.

You can't inherit from both ControllerBase and Controller at the same time.

Shakibuz_Zaman
  • 260
  • 1
  • 14
0

In my case I had a public method in my Rest Controller that was decorated with both HttpGet() and a Route(). I removed the Route() and this fixed plus the Swagger generated the proper route itself in the UI

Guy_g23
  • 316
  • 2
  • 7