-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The method 'Post' on path '/api/Products' is registered multiple times. #664
Comments
Works for me: 532cd25 Can you tell me how to change the unit test to reproduce your problem? |
Thanks, I'll try to make the unit test fail ;) |
Can you confirm that this is still a problem with v10.4? |
I downloaded v10.6 today and tried it. I ran into the same issue, for what it is worth. However, in full discloser this is the first time I have used this project. |
Have you tried "api/{controller}/{action}/{id}" as template? |
I was running against a different set of endpoints than what was used in the description above. The controller in question declared the same route pattern but distinguished between them via explicit HTTP verbs declared as attributes. After running into the issue and then reading the above I downgraded to v9.12 and everything worked as desired. |
The issue is reproduced in version 10.6. 10.4 version seems to work fine |
Maybe a regression of #738 |
Is this still an open issue with v11.1? If yes, we have to investigate further... |
@RSuter I was just looking through some of the references and I believe the op referenced issue might be present in 11.3.0 but let me know if it is just me. Asp.Net Core v1.1.2 snip from controller
swagger.json returns the following exception System.InvalidOperationException: The method 'Get' on path '/v1/Sftp' is registered multiple times (check the DefaultUrlTemplate setting [default for Web API: 'api/{controller}/{id}'; for MVC projects: '{controller}/{action}/{id?}']). Note: I went and applied [SwaggerOperation("xyz")] to the separate HttpGet methods but no change in the result. |
@RSuter I have installed a few versions of NSwag.AspNetCore down to v10.0.0 and the issue was still present. For now I have changed the controller as follows and everything generates nicely.
Looks like the swagger document is aware of using the Controller method name though: "/v1/Sftp": { |
The problem is that
and
have the same route and HTTP method (GET). The SwaggerOperation name is just used for the OperationId, it does not change the route or HTTP method... The question is now: Can you actually call both operations with HTTP requests? What are the actual routes processed by Web API? If this works, then the NSwag handling is wrong - but I need to know how Web API is handling this... |
In this example, the following routes work just fine (webapi) but swagger fails to generate--
(respectively, and I realize my pathing should be SftpUser ;D) My implementation of RequredFromQueryAttribute and RequiredFromQueryActionConstraint follows, without it, I would normally get the Microsoft.AspNetCore.Mvc.Internal.AmbiguousActionException for multiple matching routes.
|
I think the problem is that this cannot be described with swagger, because there can only be one operation per route and /v1/Sftp (GetAll) Have the same route |
I had this issue while using a dotnet core project targeting net462. The controller in question had a single get method. I think the issue might have something to do with .net core sharing a single controller between MVC and WebAPI. I had to filter the assembly types specifically down to the folder in which I kept my ApiControllers. I was able to overcome the issue by using the following snippet: \* in startup.cs Configure method *\
var assembly = Assembly.GetAssembly(typeof(Startup));
\* where path is path to api controllers... *\
var path = ".Controllers.Api.";
var assemblyTypes = assembly.GetTypes()
.Where(x => x.FullName != null && x.FullName.StartsWith($"{assembly.GetName().Name}.Controllers.Api."));
app.UseSwaggerUi(assemblyTypes, settings =>
{
settings.IsAspNetCore = true;
settings.DefaultPropertyNameHandling = PropertyNameHandling.CamelCase;
}; I'm swamped the rest of the evening, but I'm happy to provide a project sample that exhibits this issue. |
@RSuter This issue is tagged as done - is a fix ready for the next release? This is a fairly common occurrence in a large WebApi project - C# even allows you to have the same function name with overloaded parameters. |
The problem is that this cannot be described with swagger. The only solution would be to merge these operation into one swagger operation. But i think this is not worth the effort. You should design your api for swagger... |
@RSuter The API I am trying to generate Swagger docs for is over 4,000 lines of code, so it isn't feasible to completely re-architect the way it was built. Is there any way to make the endpoints unique based on a hash, function name, parameters, or something else? I believe that structuring APIs this way is fairly common and is well within the best practices for defining endpoints. I am also confused why using something like |
SwaggerOperation only sets the operationId in the spec, but the paths are still the same. The problem is the spec: You can only have one operation per path and HTTP method (and the query params are not part of the path). How would you describe your API with Swagger then? |
API endpoints are like functions and I would argue that the query params are part of the path. You need to know the function parameters to call a function; you also need to know the query parameters to call an API endpoint. I am new to Swagger, so forgive my lack of knowledge, but if the purpose of a tool is to document API endpoints, then one would assume that the tool supports expressing API documentation in every way an API endpoint can be defined. |
I'm have completely the same opinion as you, and yes, Swagger/Open API has some (serious) limitations and you cannot describe every possible API... https://swagger.io/specification/#pathsObject As I said, it would be possible to merge API operations with the same path into one operation - but in this case you would loose information (you only have one operation in the description). |
From https://swagger.io/specification/#pathsObject
violated for example by:
|
Interesting - I had no idea that the Swagger spec was so limited/strict. I am curious what the reasoning is for this restriction - it is clearly functionally possible since it is supported by tools like C# WebApi etc. Thank you for the information - it leaves me stuck, but it is good to know that you need to build an Api within the rules of Swagger if you want to use it. |
@nkm8 See domaindrivendev/Swashbuckle.WebApi#142 (comment) for some background information about the query parameters not being part of the path:
|
@stijnherreman That is some awesome insight; thank you for the link. It is nice to see that these considerations were brought up when the spec was created, but unfortunate that they weren't directly addressed. The example of different return types (list vs. single item) is the type of occurrence I see most often in our API. Our list of controllers is ~100, with several endpoints for each controller, so it isn't possible to re-structure the API design. I will definitely follow the swagger spec for future endpoints to allow us to leverage swagger documentation for all new code. |
FYI you may also get this kind of message if you're using API versioning with multiple versions of the same action, and you haven't narrowed the swagger document contents down to a single version (set your version in the ApiGroupNames property when configuring the generator settings). |
Looks similar to a previous issue but it happens with the 9.10 version. My API is built with ASP.NET Web API 5.2.3
I keep getting the following exception:
Here's my controller signature:
And finally, here's my code that returns the Swagger JSON document:
The text was updated successfully, but these errors were encountered: